                                                               ++   322

                                             III

                                    -
                                        

     II      ++:   
(int  double),   (string  vector)  ,   
 .   III  ,      ,
   .
       ++    main(),  
   .   ,   
,   main().     
,    ,   .   7
   ++.
      ,      
       .     
,     .    
 ,         
. ,         
,        
    ,   .    
  ,    
.   ,   ++,   
 8.
       ++   ,
    III.     . ,
       ,    
       ,   
. ,       , ,  int, string
 ..,  print().      

                                                               ++   323

       ,    .
         . 
 9 ,        
     .
    ,   ,   .
    ,     
     ,
    ,     . 
    10.
        ,    
 (),  ,   .    
       
.    , ,   
 ,      
.  ++    ,  
      .    
 11.
   ,       
    .   12  
          6  
 .

                                  7. 

     ,    ( 3),   
    ( 4)   ( 5).   ,   
       ,    
      .  ,    
        ,    
          .  
        ,    . 
         : 
    (inline), ,       
    ,    main().      
         .

                                 7.1. 

       ,  .  
    .  ,   ,
   ,  .     
.     ,   .
       void. ,
  ,   ;     .
  ,  ,      
.   :

                                                             ++   324
 
   inline int abs( int obj )
   {
      //    iobj
      return( iobj < 0 ? -iobj : iobj );
   }

   inline int min( int p1, int p2 )
  {
     //     
     return( pi < p2 ? pi : p2 );
  }

   int gcd( int vl, int v2 )
   {
      //    
      while ( v2 )
      {
         int temp = v2;
         v2 = vl % v2;
         vl = temp;
      }
      return vl;
   }

      ,      
.    ,      
 , .    ,  . 
  main()   abs()     min()  gcd().
 main()    main.C.

   #include <iostream>

   int main()
   {
      //     
      cout << "  : ";
      int i;
      cin >> i;
      if ( !cin ) {
         cerr << "!?   -  !\n";
         return -1;
      }

      cout << "  : ";
      int j;
      cin >> j;
      if ( !cin ) {
         cerr << "!?   -  !\n";
         return -2;
      }

      cout << "\nmin: " << min( i, j ) << endl;
      i = abs( i );
      j = abs( j );
      cout << ": " << gcd( i, j ) << endl;

      return 0;
   }

                                                             ++   325

         .   
 (inline),        .   
   ,      , 
       .   
    ,    
.         
  return.
          ,  
     .   
  ,         .
       .    
   ,     . 
     ,  ,  
,  .
         ,   
.      .  
    .
       main.C    abs(), min()  gcd(), 
       .    ,
  ,   :

   int abs( int );
   int min( int, int );
   int gcd( int, int );

(       ,  
.)
    (    17)    
 ,    ,   
.  ,      .  
 ,   .   
    .   localMath.h:

   //      gcd.
   int gcd( int, int );
   inline int abs(int i) {
      return( i<0 ? -i : i );
   }

   inline int min(int vl.int v2) {
      return( vl<v2 ? vl : v2 );
   }

   17  ,   ,    
          !  . .

                                                             ++   326

        .      , 
    ( )    
.      ,   
   .     ,  
   min(), abs()  gcd().
       main.C,    :

     : 15
     : 123

  :

   mm: 15
   : 3

                          7.2.  

             
,    .       
.

                     7.2.1.    

        ,  int  double,
,  int&  double*,     
 .       void, 
  ,      :

   #include <string>
   #include <vector> class Date { /*  */ };
   bool look_up( int *, int );
   double calc( double );
   int count( const string &, char );
   Date& calendar( const char );
   void sum( vector<int>&, int );

             .
  :

   //       
   int[10] foo_bar();

          :

                                                             ++   327

   int *foo_bar();

(      .)
       ,   . :

   // :     
   list<char> foo_bar();

(    .     . 
 7.4.)
          .  
   :

   // :    
   const is_equa1( vector<int> vl, vector<int> v2 );

      ++    ,   
  int.  ++   .  
is_equal()  :

   // :    
   const bool is_equa1( vector<int> vl, vector<int> v2 );

                         7.2.2.   

        . ,    ,
     ,      void.
,   :

   int fork();
   int fork( void );

        ,  .   
   ,    .    
   ,      
:

   int manip( int vl, v2 ); // 
   int manip( int vl, int v2 ); // 

                                                             ++   328

       . ,    ,
       .      
      . :

   void print( int *array, int size );

                
.       .
   ++      ,      , 
  .    .  
        ,   
     .   
  . (    
 9.)

               7.2.3.    

    gcd()   :

   int gcd( int, int );

      ,      int.  
   ,     
     .
    ,     gcd()    char*?

   gcd( "hello", "world" );

          ,   ?   ? 
,      24  312?

   gcd( 24312 );

          , 
       . ++
    .    
 :

   // gcd( "hello", "world" )
   error: invalid argument types ( const char *, const char * ) --
   expecting ( int, int )
   :    ( const char *, const char * ) --
    ( int, int )

   // gcd( 24312 )
   error: missing value for second argument
   :    

           double?    
  ?

   gcd( 3.14, 6.29 );

                                                             ++   329

        4.14,   double     int.
,        .  
    int (  )   
,    , .   
   ,   
.   

   gcd( 3, 6 );

    3.
   ++    .    
     .     
   ,    
.         ,
    .     
  ,      :   
     .
             
    .      
.

                                     7.1

         ? .

   (a) set( int *, int );
   (b) void func();
   (c) string error( int );
   (d) arr[10] sum( int *, int );

                                    7.2

       :
      compare,        matrix 
   bool.
      extract  ,   set  
  int. (  set    6.13.)

                                    7.3

     :

   double calc( double );
   int count( const string &, char );
   void sum( vector<int> &, int );
   vector<int> vec( 10 );

          ?

                                                             ++   330

   (a) calc( 23.4, 55.1 );
   (b) count( "abcda", 'a' );
   (c) sum( vec, 43.8 );
   (d) calc( 66 );


                               7.3.  

        .    
         ,   
         .  
    .
          ,   
  .     
  .
          , ..
  .         
,   .       
  .        
 .       .
          . ,
          
 .          
 ,    .   
        .
             
:

       .   
            
       ;
          .
    , swap()     ,  
       :

   // swap()     !
   void swap( int vl, int v2 ) {
      int tmp = v2;
      v2 = vl;
      vl = tmp;
   }

   swap()      .   , 
      ,  . 
 ,   :

                                                             ++   331

   #include <iostream>
   void swap( int, int );

   int main() {
      int i = 10;
      int j = 20;

      cout << " swap():\ti: "
           << i << "\tj: " << j << endl;

      swap( i, j );

      cout << " swap():\ti: "
           << i << "\tj: " << j << endl;

      return 0;
   }

     :

    swap(): i: 10 j: 20
    swap(): i: 10 j: 20

       .    
.      swap()   :

   // pswap()   ,
   //   vl  v2
   void pswap( int *vl, int *v2 ) {
      int tmp = *v2;
      *v2 = *vl;
      *vl = tmp;
   }

    main()    .    
   :

   pswap( &i, &j );

      :

    swap(): i: 10 j: 20
    swap(): i: 20 j: 10

        .   
 swap()  :

                                                             ++   332

   // rswap()   ,
   //    vl  v2
   void rswap( int &vl, int &v2 ) {
      int tmp = v2;
      v2 = vl;
      vl = tmp;
   }

       main()     swap():

   rswap( i, j );

     main(),     .

                              7.3.1. -

          
  .       
.  -,   l-   
  .
       - ? -, , 
          (.
   swap()). -,    
  . -,      .
    .
     ,  -   
,  look_up(),        
.    look_up()  ,    ,
   ,   .     
 ,      .  ,
 - occurs    .

                                                             ++   333

   #include <vector>

   // - 'occurs'
   //    
   vector<int>::const_iterator look_up(
         const vector<int> &vec,
         int value, //  
         int &occurs ) //  
   {
      // res_iter  
      //    
      vector<int>::const_iterator res_iter = vec.end();
      occurs = 0;
      for ( vector<int>::const_iterator iter = vec.begin();
            iter != vec.end();
            ++iter )
         if ( *iter == value )
         {
            if ( res_iter == vec.end() )
               res_iter = iter;
            ++occurs;
         }
      return res_iter;
   }

    ,   -   ,  
      .     
      ,    
    .  -,  
    ,    ,   
. :

   class Huge { public: double stuff[1000]; };
   extern int calc( const Huge & );

   int main() {
      Huge table[ 1000 ];
      // ...  table

      int sum = 0;
      for ( int ix=0; ix < 1000; ++ix )
         // calc()    
         //  Huge
         sum += calc( tab1e[ix] );
         // ...
   }

       -,   
  ,          
  .  -   
 ,        .   

                                                             ++   334

       
 .
         xx  foo().
   foo_bar()     ,  
,   foo_bar()    . 
  :

   class X;
   extern int foo_bar( X& );

   int foo( const X& xx ) {
      // :  
      //     
      return foo_bar( xx );
   }

       ,     
foo_bar().      :

   extern int foo_bar( const X& );
   extern int foo_bar( X ); //   

        xx,   :

   int foo( const X &xx ) {
      // ...
      X x2 = xx; //   
      // foo_bar()   x2,
      // xx  
      return foo_bar( x2 ); // 
   }

   -      .  ,
      ,   
   ,   ,   .  
,       :

   void ptrswap( int *&vl, int *&v2 ) {
      int *trnp = v2;
      v2 = vl;
      vl = tmp;
   }

   

   int *&v1;

                                                             ++   335

   : v1        int.
  main(),   rswap(),   
ptrswap():

   #include <iostream>

   void ptrswap( int *&vl, int *&v2 );

   int main() {
      int i = 10;
      int j = 20;

      int *pi = &i;
      int *pj = &j;

      cout << " ptrswap():\tpi: "
           << *pi << "\tpj: " << *pj << endl;

      ptrswap( pi, pj );

      cout << " ptrswap():\tpi: "
           << *pi << "\tpj: " << pj << endl;

      return 0;
   }

      :

    ptrswap(): pi: 10 pj: 20
    ptrswap(): pi: 20 pj: 10


                 7.3.2. -  -

       -,    -? 
 ,        , 
      .  :  
  ?
        3.6,      
 ,     .     
        .
      ,       -
,      ,     :

   class X;
  
   void manip( X *px )
   {
      //   0  
      if ( px != 0 )
      //     ...
   }

                                                             ++   336

   -     ,      
. :

   class Type { };
   void operate( const Type& p1, const Type& p2 );

   int main() {
      Type obj1;
      //  objl  
      // :      0
      Type obj2 = operate( objl, 0 );
   }

              
   (    ),   
.
        -   
 .       
 . (      15.) 
 .    Matrix ().   
     :

   Matrix a, b, c;
   c = a + b;

             
 .       
operator+. ,   :

   Matrix //   - Matrix
   operator+( //   
      Matrix m1, //   
      Matrix m2 //   
   )
   {
      Matrix result;
      //  
      return result;
   }

          Matrix   :

   a + b;

,  ,   . ,   
   .       
  operator+(),     Matrix  ,
          .

                                                             ++   337

    ,        , 
  .    operator+():

   //   -
   operator+( Matrix *ml, Matrix *m2 )
   {
      Matrix result;
      //  
      return result;
   }

   ,    ,      
     .    -
     .   
    :

   &a + &b; // ,   

          ,  -    
.      :

   //     
   // &a + &b    Matrix
   &a + &b + &c;

        ,      :

   &( &a + &b ) + &c;

    ,  -    .  ,
-    ,  .   
 ,    l-,   .  
.       Matrix   
 ,     .    
   Matrix:

   //   -
   operator+( const Matrix &m1, const Matrix &m2 )
   {
      Matrix result;
      //  
      return result;
   }

         Matrix   :

                                                             ++   338

   a + b + c;

       ++   ,    :
     .

                            7.3.3. -

     ++     ,       ,
 , . , 

   void putValues( int[ 10 ] );
   void putValues( int[ 10 ] );

  ,     

        .    
:

   //    putValues()
   void putValues( int* );
   void putValues( int[] );
   void putValues( int* );
   void putValues( int[ 10 ] );

         :

          
    ,     .    ,
          . 
        ,      
    ,    :

     void putValues( const int[ 10 ] );

         .    
       .     
    .  :

   void putValues( int[ 10 ] ); //   int*

   int main() {
      int i, j [ 2 ];
      putValues( &i ); // : &i is int*;
      //     
      putValues( j ); // : j -  0-  - int*;
      //     

         ,    
  int*   .    , 
   ,  .

                                                             ++   339

      C-   ,  
  .         
    .      ,
   0.      
 . :

   void putValues( int[], int size );

   int main() {
      int i, j[ 2 ];
      putValues( &i, 1 );
      putValues( j, 2 );
      return 0;
   }

putValues()      :

    ( 10 )< 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 >

 10    .     putValues(),  
  :

   #include <iostream>

   const lineLength =12; //    

   void putValues( int *ia, int sz )
   {
      cout << "( " << sz << " )< ";
      for (int i=0;i<sz; ++i )
      {
         if ( i % lineLength == 0 && i )
            cout << "\n\t"; //  

          cout << ia[ i ];

          // ,    ,
          //  
          if ( i % lineLength != lineLength-1 &&
               i != sz-1 )
             cout << ", ";
          }
          cout << " >\n";
   }

        -    
.       ,    
   .

                                                             ++   340

   //  -     10 
   void putValues( int (&arr)[10] );

   int main() {
      int i, j [ 2 ];
      putValues(i); // :
                    //      10 
      putValues(j); // :
                    //      10 
      return 0;
   }

          ,  
putValues()       10 . , 
   ,    :

   #include <iostream>

   void putValues( int (&ia)[10] )
   {
      cout << "( 10 )< ";
      for ( int 1 =0; i < 10; ++i ) { cout << ia[ i ];

      // ,    ,
      //  
      if ( i != 9 )
         cout << ", ";
   }
   cout << " >\n";
   }

             
  . (      6.  
     .)
       putValues() ,   
. ,        int.  
double*    ,  long*     ..  
      10   int.  
     .    
   , , ,    
 ,      . 
      putValues() ,   
    :

   template <class Type>

   void putValues( Type *ia, int sz )
   {
      //  ,   
   }

        .   class , 
 Type   ,    

                                                             ++   341

putValues()       int, double, string .. (  10 
    .)
       .     
    ,  . :

   putValues( int matrix[][10], int rowSize );

    matrix    ,     
  .    matrix :

   int (*matrix)[10]

           .   
 matrix         int.    
,        . 
   ,    , 
.
   ,    *matrix  -   
  . 

   int *matrix[10];

 matrix       int.

                7.3.4.     
                                

     ,    6,   
  . ,   putValues() 
   vector<int>    .
          
,   . , vector<int>  
.     ,   - 
        .
 vector<int>    . , 
   putValues()  :

                                                             ++   342

   #include <iostream>
   #include <vector>

   const lineLength =12; //    

   void putValues( vector<int> vec )
   {
      cout << "( " << vec.size() << " )< ";
      for ( int i = 0; i < vec.size(); ++1 ) {
         if ( i % lineLength == 0 && i )
            cout << "\n\t"; //  

         cout << vec[ i ];

         // ,    ,
         //  
         if ( 1 % lineLength != lineLength-1 &&
              i != vec.size()-1 )
            cout << ", ";
      }
      cout << " >\n";
   }
 
    main(),     putValues(),  :

   void putValues( vector<int> );

   int main() {
      int i, j[ 2 ];
      //  i  j  

      vector<int> vec1(1); //    1 
      vecl[0] = i;
      putValues( vecl );
      vector<int> vec2; //   
      //    vec2
      for ( int ix = 0;
            ix < sizeof( j ) / sizeof( j[0] );
            ++ix )
         // vec2[ix] == j [ix]
         vec2.push_back( j[ix] );
      putValues( vec2 );

      return 0;
   }

   ,   putValues()  .   
          .
    ,   
  .
        putValues()?
   ,        , 
,       :

   void putValues( const vector<int> & ) { ...

                                                             ++   343

                      7.3.5.    

         ,   
     ,     . 
       
 .
             
   ,     .
,       , 
 ,      ,   
 :

   char *screenInit( int height = 24, int width = 80,
                     char background = ' ' );

   ,       ,   -
.   ,    ,  
    .    screenInit()
:

   char *cursor;

   //  screenInit(24,80,' ')
   cursor = screenInit();

   //  screenInit(66,80,' ')
   cursor = screenlnit(66);

   //  screenInit(66,256,' ')
   cursor = screenlnit(66, 256);

   cursor = screenlnit(66, 256, '#');

          (
 ),        
    .   
    background,     height  width.

   //  screenInit('?',80,' ')
   cursor = screenInit('?');
   // ,  screenInit(24,80,'?')
   cursor = screenInit( , ,'?');

             
. ,         ,
    .  screenInit() 
(,    ),   height  
  .

                                                             ++   344

              .
         ,   
.

   // : width     ,
   //     height
   char *screenlnit( int height = 24, int width,
   char background = ' ' );

            .  
:

   // tf.h
   int ff( int = 0 );

   // ft.
   #include "ff.h"
   int ff( int i = 0) { ... } // 

         ,   
   ( ),     .
     ,       
   ,   .
            
 .        
. ,    UNIX   chmod(), 
   .       
<cstdlib>:

   int chmod( char *filePath, int protMode );

protMode    ,  filePath     .  
    ,    chmod(),
      ,    
  :

   #include <cstdlib>
   int chmod( char *filePath, int protMode=0444 );

         :

   file int ff( int a, int b, int  = 0 ); // ff.h

   ,        b?
  ,       :

                                                             ++   345

   #include "ff.h"
   int ff( int a, int b = 0, int  = 0 ); // 

      :

   #include "ff.h"
   int ff( int a, int b = 0, int  ); // 

     ,     ff(),  b  
,     .    
    .     ff()  :

   #include "ff.h"
   int ff( int a, int b = 0, int  ); // 
   int ff( int a = 0, int b, int  ); // 

          ,  
:

   int aDefault();
   int bDefault( int );
   int cDefault( double = 7.8 );
   int glob;
   int ff( int a = aDefault() ,
   int b = bDefau1t( glob ) ,
   int  = cDefault() );

       ,       .
   cDefault()   ,    
ff()    .

                                7.3.6. 

            . 
      (...),  
  .    ,   
       .
    :

   void foo( parm_list, ... );
   void foo( ... );

                                                             ++   346

         .    
    ,    
  .      .
         printf()
  .     C-:

   int printf( const char* ... );

    ,     printf()     
 const char*.   ,  , ,
     .     
,    %,     .
, 

   printf( "hello, world\n" );

   . 

   printf( "hello, %s\n", userName );

  .  %     ,   s,
  ,         .
             
       .
,     .
   ,    :

   void f();
   void f( ... );

      f()     ,     
   . 

   f( someValue );
   f( cnt, a, b,  );

    . 

   f();

     .

                                          7.4

        ? .

                                                             ++   347

   (a) void print( int arr[][], int size );
   (b) int ff( int a, int b = 0, int  = 0 );
   (c) void operate( int *matrix[] );
   (d) char *screenInit( int height = 24, int width,
                          char background );
   (e) void putValues( int (&ia)[] );

                                      7.5

          .  .

   (a) char *screenInit( int height, int width,
                         char background = ' ' );
       char *screenInit( int height = 24, int width,
                         char background );

   (b) void print( int (*arr)[6], int size );
       void print( int (*arr)[5], int size );

   (c) void manip( int *pi, int first, int end = 0 );
       void manip( int *pi, int first = 0, int end = 0 );

                                        7.6

     .

   void print( int arr[][5], int size );
   void operate(int *matrix[7]);
   char *screenInit( int height = 24, int width = 80,
                     char background = ' ' );

       .    .

   (a) screenInit();
   (b) int *matrix[5];
       operate( matrix );
   (c) int arr[5][5];
       print( arr, 5 );

                                       7.7

     putValues( vector<int> ),    7.3.4,
,      list<string>.     
.        :

( 2 )

                                                             ++   348

   <
   "first string"
   "second string"
   >

     main(),    putValues()  
 :

   "put function declarations in header files"
   "use abstract container types instead of built-in arrays"
   "declare class parameters as references"
   "use reference to const types for invariant parameters"
   "use less than eight parameters"

                                  7.8

         -?     -?
     .

                                7.4.  

         return.   
.      ,    
.  return     :

   return expression;
 
       ,     
 void.  return    ,  
  . (  return  
break,    5.8.)    
  return. :

   "put function declarations in header files"
   "use abstract container types instead of built-in arrays"
   "declare class parameters as references"
   "use reference to const types for invariant parameters"
   return;

                                                             ++   349

   void d_copy( double "src, double *dst, int sz )
   {
      /*   "src"  "dst"
       *   ,    
       */

      // ,        0
      if ( !src || !dst )
         return;

     // ,
     //        
     if ( src == dst )
        return;

     //  
     if ( sz == 0 )
        return;

      //    ?
      //    - 
      for ( int ix = 0; ix < sz; ++ix )
         dst[ix] = src[ix];

      //    
   }

       return   ,   
.        ,  
 .    factorial(),    
 ,  return  :

   return val * factorial(val-1);

    ,    void     , 
   return,    . 
     ,    
.     -  ,  
   :

                                                             ++   350

   //    Matrix
   #include "Matrix.h"

   bool is_equa1( const Matrix &ml, const Matrix &m2 )
   {
      /*     Matrix ,
       *  true;
       *    - false
       */

      //   
      if ( ml.colSize() != m2.co1Size() )
        // :   
        return;

      //   
      if ( ml.rowSize() != m2.rowSize() )
         // :   
         return;

      //    , 
      //    
      for ( int row = 0; row < ml.rowSize(); ++row )
         for ( int col = 0; co1 < ml.colSize(); ++co1 )
            if ( ml[row][col] != m2[row][col] )
               return false;
       // :   
       //   
   }

            
,     .   
 ,   . ( 
   4.1.4.)
         , .. 
     ,   
return. :

   Matrix grow( Matrix* p ) {
      Matrix val;
      // ...
      return val;
   }

grow()     ,   
val.
      ,  ,    
.       l-  val 
   val    .    , 
grow()  :

                                                             ++   351

   Matrix& grow( Matrix* p ) {
      Matrix *res;
      //     Matrix
      //  
      // res    
      //   *p  *res
      return *res;
   }

      ,       
     .    
   .     
 . (    14.8.)
       ,     
 :

       ,    
      . (     
       8.3.)       
    ,   . :

     // :     
    Matrix& add( Matrix &m1, Matrix &m2 )
    {
        Matrix result:
        if ( m1.isZero() )
           return m2;
        if ( m2.isZero() )
           return m1;

        //    
        // :     
       //  
       return result;
    }

            .  
            :

     Matrix add( ... )

     l-.     
    . :

                                                             ++   352

   #include <vector>

   int &get_val( vector<int> &vi, int ix ) {
      return vi [ix];
   }

   int ai[4] = { 0, 1, 2, 3 };
   vector<int> vec( ai, ai+4 ); //  4  ai  vec

   int main() {
      //  vec[0]  1
      get_val( vec.0 )++;
      // ...
   }

         
    const:

  const int &get_val( ... )

    ,  l-  ,  
  ,     
   IntArray   2.3.

                7.4.1.      
                               

            
. (      .)  
   ,       
.
       . :

   int glob;
   int main() {
      //  
   }

    glob  . (  8    
    .)    
           
,         .
   :

   ,   ,      
    .       ;
         .  
            ;

                                                             ++   353

        ,    
     .  ;
     ,    
    (  ,     .  
        7.5.);
      (threads),     
         . 
            .
    (      ++ .  
     Distributing Object Computing in C++ (Steve Vinoski and Doug Schmidt) 
    [LIPPMAN96b].)

     ,      
     .
          . , 
     .    
      ,   . 
   .
         .    
,    ,   
      
      ,  
  ,   ,  , 
.

                                7.9

      return? ,    
 ,     .

                               7.10

          :

   vector<string> &readText( ) {
      vector<string> text;
      string word;
      while ( cin >> word ) {
         text.push_back( word );
         // ...
      }
      // ....
      return text;
   }

                                 7.11

           ?   
  .

                                                             ++   354

                                7.5. 

   ,       ,  .
:

   int rgcd( int vl, int v2 )
   {
      if ( v2 != 0 )
         return rgcd( v2, vl%v2 );
      return vl;
   }

         ,   
   .       
 .  rgcd()      .
   

   rgcd( 15, 123 );

 3 (. . 7.1).

 7.1.   rgcd (15,123)

	vl 	v2 	return

	15 	123 	rgcd(123,15)
	123 	15 	rgcd(15,3)
	15 	3 	rgcd(3,0)
	3 	0 	3

    ,

   rgcd(3,0);

  .     , 
     . ,   
(percolates) ,      ,  rgcd()  
.
       ,   
() .        . , 
,    .
    .   n      1
 n. ,  5  120: 1  2  3  4  5 = 120.
         :

                                                                  ++   355

   unsigned long
   factorial( int val ) {
      if ( val > 1 )
         return val * factorial( val-1 );
      return 1;
   }

       val  1.

                                    7.12

    factorial()   .

                                    7.13

    ,    factorial()  :

   if ( val != 0 )


                           7.6.  

      min():

   int min( int vl, int v2 )
   {
      return( vl < v2 ? vl : v2 );
   }

          :

    ,      min(),  
           ,   v1  v2
      ;
         , 
    300. ,      :
    ( vl == v2 || vl < v2 )
              
      ;
    .    ;
          .

        :    , 
   .   
,         
 .    .  
       . :

   int minVa12 = min( i, j );

                                                              ++   356

   

   int minVal2 = i < j ? i : j;

    ,       min()   .
    min()        inline 
      :

   inline int min( int vl, int v2 ) { /* ... */ }

   , ,   inline     .
   ,      
 . ,   (,  rgcd())    
    (      ).  
1200      .     
   , ,   . 
        
  . ,   - size() 
 IntArray   2.3.
           .   
,       ,    
.  ,          
 .       compute.C  draw.C,
        min().   
,   : ,    
   ,       .
           
    ,     .   ,  
         ;
        
  .
    min()   ,    
  ++;     ,   
12   .  min()   ,     
  ,   int. ( 
   10.)

                        7.7.   extern "C" A

       ,    , 
  ,    ,     
 . ,        
   .
   ,      ,    
      :

                                                              ++   357

   //      
   extern "C" void exit(int);

   //      
   extern "C" {
      int printf( const char* ... );
      int scanf( const char* ... );
   }

   //      
   extern "C" {
      #include <cmath>
   }

           extern,   
 ,       .   
  ,     .  
         
     .    ,  
 ,    ,     
.   extern "C"      
,   printf()  scanf()    .   
      ,      
 .
           
 #include,       
    ,    .  
      cmath    .
          .  
   :

   int main() {
      // :     
      //   
      extern "C" double sqrt( double );
      double getValue(); //

      double result = sqrt ( getValue() );
      //...
      return 0;
   }

       ,      main(), 
 :

   extern "C" double sqrt( double );

   int main() {
      double getValue(); //

      double result = sqrt ( getValue() );
      //...
      return 0;

                                                                ++   358

   }

            , 
  ,   .
     ++      ?  extern "C"
   :

   //  calc()       C
   extern "C" double calc( double dparm ) { /* ... */ }

          ,   
               
     . :

   // ---- myMath.h ----
   extern "C" double calc( double );
   // ---- myMath.C ----
   //  calc()  myMath.h
   #include "myMath.h"
   //   extern "C" calc()
   //  calc()       C
   double calc( double dparm ) { // ... }

           extern "C"  
 .    ,    
++.         . ,
extern "Ada"  ,    Ada; extern "FORTRAN"  
FORTRAN  ..         extern 
++.   8.2  ,         
  .

                                  7.14

   exit(), printf(), malloc(), strcpy()  strlen()    
.    - ,    
  ++.

                                                               ++   359

   const char *str = "hello";

   void *malloc( int );
   char *strcpy( char *, const char * );
   int printf( const char *, ... );
   int exit( int );
   int strlen( const char * );

   int main()
   { /*    */

      char* s = malloc( strlen(str)+l );
      strcpy( s, str );
      printf( "%s, world\n", s );
      exit( 0 );
   }

            7.8.  main():   
                                 

      ,  ,      .
,  

   prog -d -o of lie dataO

        main()    
  C-   argv;  ,   .
        main()   :

   int main() { ... }

     main()     ,  
    :

   int main( int argc, char *argv[] ){...}

   argc   ,  argv C-,   
 (     ). ,  


   prog -d -o ofile data0

argc   5,  argv   :

   argv[ 0 ] = "prog";
   argv[ 1 ] = "-d";
   argv[ 2 ] = "-o";
   argv[ 3 ] = "ofile";
   argv[ 4 ] = "dataO";

                                                           ++   360

    argv[0]     ().     1 
argc-1  .
   ,      ,   argv. 
      :

prog [-d] [-h] [-v]
[-o output_file] [-l limit_value]
file_name
[ file_name [file_name [ ... ]]]

        . , , 
         :

prog chap1.doc

       :

prog -l 1024 -o chap1-2.out chapl.doc chap2.doc
prog d chap3.doc
prog -l 512 -d chap4.doc

          :

  1.       argv.      for 
       1 (,  ,  ):

     for ( int ix = 1; ix < argc; ++ix ) {
        char *pchar = argv[ ix ];
        // ...
     }

  2.   .      (-),     {
     h, d, v, l, o}.        ,  
      (   -l,     -o),  
      .  ,     , 
      switch:

     switch ( pchar[ 0 ] ) {
       case '-': {
          // -h, -d, -v, -l, -o
       }
       default: {
         //      -1
         //     -o
         //    ...
      }

                                                                   ++   361

   }

        2.
       ,   switch    
  .      :

   case '-': {
      switch( pchar[ 1 ] )
      {
         case 'd':
            //   debug
            break;
         case 'v':
            //   version
            break;
         case 'h':
            //   help
            break;
         case 'o':
            //    
            break;
         case 'l':
           //   .
           break;
      default:
         //  :
         //      
      }
   }

    -d   .     
  


   bool debug_on = false;

 true:

   case 'd':
      debug_on = true;
      break;

          :

   if ( debug_on )
      display_state_elements( obj );

                                                            ++   362

    -v       :

   case 'v':
      cout << program_name << "::"
           << program_version << endl;
      return 0;

    -h        .
        usage():

   case 'h':
      // break  : usage()  exit()
      usage();

    -o   ,       .
  -l ,      .  
  ?
        ,   :   
 ,      .   
,  true ,   :

   //  ofi1e_on==true,
   //   -   
   bool ofi1e_on = false;
   //  ofi1e_on==true,
   //   -  
   bool limit_on = false;

      -l  -o    switch:

   case 'l':
      limit_on = true;
      break;
   case 'o':
      ofile_on = true;
      break;

    ,    ,     
   :

                                                                ++   363

   //      -1
   //     -o
   //    ...
   default: {
      // ofile_on ,  -o 
      if ( ofile_on ) {
         //    
         //  ofile_on
     }
     else if ( limit_on ) { //  -l 
             //   
             //  limit_on
         } else {
             //    
         }
   }

        ,     
ofile_on:

   if ( ofile_on ) {
      ofile_on = false;
      ofile = pchar;
   }

       ,    
     .     
 atoi(),         int
(   atof(),  double).   atoi()
   ctype.h.  ,   
    limit_on:

   // int limit;
   else
   if ( limit_on ) {
      limit_on = false;
      limit = atoi( pchar );
      if ( limit < 0 ) {
         cerr << program_name << "::"
              << program_version << " : error: "
              << "negative value for limit.\n\n";
          usage( -2 );
      }
   }

        false,      . 
   :

   else
      file_names.push_back( string( pchar ));

                                                              ++   364

             .
 ,        
  .        . 
     ,    
  -    .
       ,    
 ,  . ,       
 :

prog - d dataOl
prog -oout_file dataOl

(        .)
       . (     
.)

                                                               ++   365

   #include <iostream>
   #include <string>
   #include <vector>
   #include <ctype.h>

   const char *const program_name = "comline";
   const char *const program_version = "version 0.01 (08/07/97)";

   inline void usage( int exit_value = 0 )
   {
      //      
      //      exit_value ...

      cerr << " :\n"
           << program_name << " "
           << "[-d] [-h] [-v] \n\t"
           << "[-o output_file] [-l limit] \n\t"
           << "file_name\n\t[file_name [file_name [ ... ]]]\n\n"
           << " []    :\n\n\t"
           << "-h: .\n\t\t"
           << "    \n\n\t"
           << "-v: .\n\t\t"
           << "      \n\n\t"
           << "-d: .\n\t\t   \n\n\t"
           << "-l limit\n\t\t"
           << "limit     \n\n\t"
           << "-o ofile\n\t\t"
           << ",    \n\t\t"
           << "      \n\n"
           << "file_name\n\t\t"
           << "   \n\t\t"
           << "       --\n\t\t"
           << "    \n\n"
           << ":\n\t\t"
           << "$command chapter7.doc\n\t\t"
           << "$command -d -l 1024 -o test_7_8 "
           << "chapter7.doc chapter8.doc\n\n";
       exit( exit_value );
   }

   int main( int argc, char* argv[] )
   {
      bool debug_on = false;
      bool ofile_on = false;
      bool limit_on = false;
      int limit = -1;
      string ofile;
      vector<string> file_names;

      cout << "     :\n"
           << "argc: " << argc << endl;

      for ( int ix = 1; ix < argc; ++ix )
      {
         cout << "argv[ " << ix << " ]: "
              << argv[ ix ] << endl;

         char *pchar = argv[ ix ];
         switch ( pchar[ 0 ] )
         {
            case '-':
            {
               cout << " \'-\'\n";
               switch( pchar[ 1 ] )
               {
                  case 'd':
                     cout << " -d: "
                          << "  \n";
                     debug_on = true;
                     break;
                  case 'v':

                                                              ++   366

   }

   a.out -d -l 1024 -o test_7_8 chapter7.doc chapters.doc

        :
     :

   argc: 8
   argv[ 1 ]: -d
 '-'
 -d:   
argv[ 2 ]: -l
 '-'
 -l:  
argv[ 3 ]: 1024
default:   : 1024
argv[ 4 ]: -o
 '-'
 -o:  
argv[ 5 ]: test_7_8
default:   : test_7_8
argv[ 6 ]: chapter7.doc
default:   : chapter7.doc
argv[ 7 ]: chapter8.doc
default:   : chapter8.doc
   limit: 1024
   : test_7_8
, () :
   chapter7.doc
   chapter8.doc


                    7.8.1.      

       main() ,   
 ,    .     .
:

   extern int parse_options( int arg_count, char *arg_vector );

   int main( int argc, char *argv[] ) {
      // ...
      int option_status;
      option_status = parse_options( argc, argv );
      // ...
   }

      ?      ,
        ,  . 
        .
   -    ,   
 .    -   
.      . -
  argc  argv      :

                                                           ++   367

   #include <vector>
   #include <string>

   class CommandOpt {
   public:
      CommandOpt() : _limit( -1 ), _debug_on( false ) {}
      int parse_options( int argc, char *argv[] );

      string out_file() { return _out_file; }
      bool debug_on() { return _debug_on; }
      int files() { return _file_names.size(); }

      string& operator[]( int ix );

   private:
      inline void usage( int exit_value = 0 );

      bool _debug_on;
      int _limit;
      string _out_file;
      vector<string> _file_names;

      static const char *const program_name;
      static const char *const program_version;
   };

       main():18

   #include "CommandOpt.h"

   int main( int argc, char "argv[] ) {
      // ...
      CommandOpt com_opt;
      int option_status;
      opttion_status = com_opt. parse_options (argc, argv);
      // ...
   }

                                   7.15

      -t ( )  -b (  
bufsize).    usage(). :

prog -t -b 512 dataO

                                7.16

       ,       
  .      .

                                7.17

          :


   18     CommandOpt    Web-
       Addison-Wesley.

                                                             ++   368

   prog - d dataO

     ,        
.

                                        7.18

        ,   -l  -o  
.   .      
?

                                       7.19

            .  
,  ?   .

                                      7.20

     ,     (+),   +s 
+pt,   +sp  +ps. ,  +s    , 
+p    . :

   prog +s +p -d -b 1024 dataO


                                 7.9.   

   ,      ,   
:

   sort( start, end, compare );

 start  end      .  sort()
   start  end,   compare   
   .
       compare?    
, ..   ,      ,  
       .     
  .
   (,    12   sort()     
  ++.        
sort()      .   
   .)
             
 compare   ,   .
         sort(),   , 
    ,    .
,       ,  
     compare()   (  
   6.10).

                                                                ++   369

                           7.9.1.    

       ?    , 
    ?   
lexicoCompare(),     :

   #include <string>
   int lexicoCompare( const string &sl, const string &s2 ) {
      return sl.compare(s2);
   }

       s1  s2 , lexicoCompare()  0,    
 ,  s1   s2,  ,  s1  s2.
               
   .   lexicoCompare()  
    .   :

   int *pf( const string &, const string & ) ;
   // ,   

      .   ,     
    pf,     int*. 
 ,      .  
(*)     (int   ),    pf.  
,   :

   int (*pf)( const string &, const string & ) ;
   // 

   pf        ,  
 int, .. ,  lexicoCompare().
   pf      ,   
   lexicoCompare():

   int sizeCompare( const string &sl, const string &s2 );

    calc()  gcd() ,  pf     :

   int calc( int , int );
   int gcd( int , int );

   ,     ,  :

                                                              ++   370

   int (*pfi)( int, int );

       .     
   ,        , 
,   .     .

   int printf( const char*, ... );
   int strlen( const char* );
   int (*pfce)( const char*, ... ); //    printf()
   int (*pfc)( const char* ); //    strlen()

     ,       
.

                         7.9.2.   

   ,          
 .        
    . ,   

   lexicoCompare;

  

   int (*)( const string &, const string & );

              
,  lexicoCompare  &lexicoCompare.   
  :

  int (*pfi)( const string &, const string & ) = lexicoCompare;
   int (*pfi2)( const string &, const string & ) = &lexicoCompare;

      :

   pfi = lexicoCompare;
   pfi2 = pfi;

        ,     
,   ,      
,        ,
      .    
   .     
    . :

                                                                   ++   371

   int calc( int, int );
   int (*pfi2s)( const string &, const string & ) = 0;
   int (*pfi2i)( int, int ) = 0;

   int main() {
      pfi2i = calc; // 
      pri2s = calc; // :  
      pfi2s = pfi2i; // :  
      return 0;
   }

            , 
     .

                                       7.9.3. 

         ,   . 
    .      , 
     :

   #include <iostream>

   int min( int*, int );
   int (*pf)( int*, int ) = min;

   const int iaSize = 5;
   int ia[ iaSize ] = { 7, 4, 9, 2, 5 };

   int main() {
      cout << " : min: "
           << min( ia, iaSize ) << endl;
      cout << " : min: "
           << pf( ia, iaSize ) << endl;
      return 0;
   }

   int min( int* ia, int sz ) {
      int minVal = ia[ 0 ];
      for ( int ix = 1; ix < sz; ++ix )
        if ( minVal > ia[ ix ] )
           minVal = ia[ ix ];
      return minVal;
   }

   

   pf( ia, iaSize );

         :

   (*pf)( ia, iaSize );

                                                               ++   372

       ,     ,  
    .
   ,      ,     
    .     , 
 -      .

                             7.9.4.    

        . :

   int (*testCases[10])();

   testCases      ,      
,    int    .
      ,    ,   
  .
        ,    
typedef:

   // typedef    
   typedef int (*PFV)(); // typedef    
   PFV testCases[10];

      .
    ,    testCases,  
:

   const int size = 10;
   PFV testCases[size];
   int testResults[size];
   void runtests() {
      for ( int i = 0; i < size; ++i )
        //    
        testResults[ i ] = testCases[ i ]();
   }

          ,  
  . :

   // typedef    
   typedef int (*PFV)(); // typedef    
   const int size = 10;
   PFV testCases[size];
   int testResults[size];
   void runtests() {
   for ( int i = 0; i < size; ++i )
   //    
   testResults[ i ] = testCases[ i ]();

                                                                ++   373

   int lexicoCompare( const string &, const string & );
   int sizeCompare( const string &, const string & );
   typedef int ( *PFI2S )( const string &, const string & );
   PFI2S compareFuncs[2] =
   {
      lexicoCompare,
      sizeCompare
   };

        compareFuncs,      
  :

   PFI2S (*pfCompare)[2] = compareFuncs;

          :

   (*pfCompare)

     ,  pfCompare  . [2]  
  :

   (*pfCompare) [2]

   PFI2S  ,     typedef,   . 
  ,  int      const
string &.     ,    &lexicoCompare.
          compareFuncs,    
    :

   compareFunc[ 0 ];
   (*pfCompare)[ 0 ];

      lexicoCompare  pfCompare,    
 :

   //  
   pfCompare [ 0 ]( string1, string2 ); //  
   ((*pfCompare)[ 0 ])( string1, string2 ); //  

                        7.9.5.    

     ,     .  
     ?     
   ,   :

                                                                ++   374

   int sort( string*, string*,
             int (*)( const string &, const string & ) );

        typedef    sort() 
:

   //   typedef 
   //  sort()  
   typedef int ( *PFI2S )( const string &, const string & );
   int sort( string*, string*, PFI2S );

         lexicoCompare, 
    :

   //      
   int lexicoCompare( const string &, const string & );
   int sort( string*, string*, PFI2S = lexicoCompare );
 
 sort()   :

1 void sort( string *sl, string *s2,
2    PFI2S compare = lexicoCompare )
3 {
4    //  
5    if ( si < s2 ) {
6       string elem = *s1;
7       string *1ow = s1;
8       string *high = s2 + 1;
9
10      for (;;) {
11         while ( compare ( *++1ow, elem ) < 0 && low < s2) ;
12         while ( compare( elem, *--high ) < 0 && high > s1)
14            if ( low < high )
15               1ow->swap(*high);
16            else break;
17       } // end, for(;;)
18
19       s1->swap(*high);
20       sort( s1, high - 1 );
21       sort( high +1, s2 );
22    } // end, if ( si < s2 )
23 }

   sort()      (C.A.R.Hoare).  
 .      s1  s2.  
,       
.   ,  s1  s2       
 s1    s2 ( 5).

                                                              ++   375

   elem ( 6)   .  ,   elem,
   ,    .      .
sort()       ( 20-21).
    for(;;)   ( 10-17).     
low    ,    elem ( 11).
 high    ,    elem
( 12).  low     high,    , 
         
 ( 14-16).   , elem     
. swap()   19        sort()  
 .
      ,    compare ( 11-
12).     ,   swap() 
  string,    6.11.
      main(),      :

   #include <iostream>
   #include <string>

   //       
   int lexicoCompare( const string &, const string & );
   int sizeCompare( const string &, const string & );
   typedef int (*PFI)( const string &, const string & );
   void sort( string *, string *, PFI=lexicoCompare );

   string as[10] = { "a", "light", "drizzle", "was", "falling",
                     "when", "they", "left", "the", "museum" };

   int main() {
      //  sort()      compare
      sort( as, as + sizeof(as)/sizeof(as[0]) - 1 );

      //   
      for ( int i = 0; i < sizeof(as)/sizeof(as[0]); ++i )
         cout << as[ i ].c_str() << "\n\t";
   }

     :

"a"
"drizzle"
"falling"
"left"
"light"
"museum"
"the"
"they"
"was"
"when"

           :

                                                            ++   376

   // typedef    
   typedef int functype( const string &, const string & );
   void sort( string *, string *, functype );

sort()      

   int (*)( const string &, const string & ) );

      sort() .
   , ,     ,    
     . :

   int (*ff( int ))( int*, int );

ff()   ,     int  
   

   int (*)( int*, int );

       typedef   .  PF 
 typedef,  ,  ff()    :

   //   typedef 
   //   
   typedef int (*PF)( int*, int );
   PF ff( int );

           .   
  . ,   ff()  :

   // typedef    
   typedef int func( int*, int );
   func ff( int ); // :   ff() - 

                 7.9.6.   ,   extern "C"

       ,    
.      . ,
 pf   -:

   extern "C" void (*pf)(int);

                                                         ++   377

    pf  ,    .

   extern "C" void exit(int);
   // pf   C- exit()
   extern "C" void (*pf)(int) = exit;
   int main() {
      // ...
      //  -,   exit()
      (*pf)(99);
   }

   ,         
,            
  . ,   -    
++ (      ),  .  
  :

   void (*pfl)(int);
   extern "C" void (*pf2)(int);
   int main() {
      pfl = pf2; // : pfl  pf2   
      // ...
   }

   ,     ++      
++ .      ,
    .
        ,    ,
   .
       pfParm     -.
     ,    
:

   // pfParm -   -
   extern "C" void f1( void(*pfParm)(int) );

   , f1()  -       -
. ,         , 
  ,  ,    ,  
 ,   . ( ,     ++, 
     ++   ,  
  ,       .)
            ,   
  ++,       -? 
  typedef. :

                                                            ++   378

   // FC   :
   // -    int,    
   extern "C" typedef void FC( int );
   // f2() - C++    -
   //   -
   void f2( FC *pfParm );

                                   7.21

     7.5    factorial().  
  .         11.

                                  7.22

      :

   (a) int (*mpf)(vector<int>&);
   (b) void (*apf[20])(doub1e);
   (c) void (*(*papf)[2])(int);

        ,   typedef?

                            7.23

       ,     <cmath>:

   double abs(double);
   double sin(double);
   double cos(double);
   double sqrt(double);

          -    
 ?  main(),   sqrt()   97.9
  .

                          7.24

      sort().   

   int sizeCompare( const string &, const string & );

           , 
sizeCompare()  0;     ,   ,
  ,  . ,    
 size()  string.  main()   sort(),  
     sizeCompare().
