前回の構造体の説明(基本文法と複合データ)に続いて、第2段。 関数と構造体の説明を行う。
構造体の一括代入
構造体同士の代入文は、要素の一括代入が可能なことを説明する。 この時に、古いC言語(K&R)の文法の話も交えて、古い文法も紹介する。
struct A { char n[10] ; int a ; } ; struct A a[ 10 ] ; struct A b ; // 一括代入の文法を知らないと... strcpy( a[0].n , b.n ) ; a[0].a = b.a ; // ANSI-Cであれば、この書き方ができる。 a[ 0 ] = b ; // K&Rであれば、 memcpy( &a[0] , &b , sizeof( struct A ) ) ;
値渡しとポインタ渡し
前期の説明での、値渡し・ポインタ渡しを説明し、配列は基本ポインタ渡しであることの復習を行う。
// 値渡し void foo( int x ) { x++ ; printf( "%d" , x ) ; } void main() { int a = 123 ; foo( &a ) ; foo( &a ) ; } // ポインタ渡し void foo( int* p ) { (*p)++ ; printf( "%d" , *p ) ; } void main() { int a = 123 ; foo( &a ) ; foo( &a ) ; } // 配列のポインタ渡し void foo( int x[] ) { x[0] = 123 ; x[1] = 234 ; } void main() { int a[ 2 ] ; foo( a ) ; printf( "%d %d" , a[0] , a[1] ) ; }
構造体とポインタ渡し
構造体を使ったプログラムでは、ポインタ渡しが多用される。 下記のように、構造体の中身を触る関数と、利用する関数に分けると、 プログラムで、データ構造の修正が容易になることを説明する。 この後、(*p).name 等を例にとり、型の概念を説明する。 最後に、p->name といったアロー演算子を紹介する。 教科書の中で、式の部分の型を説明してくれているものって少ない!!
struct Person { char name[ 10 ] ; int age ; } ; void read_person( struct Person* p ) { scanf( "%s %d" , (*p).name , &((*p).age) ) ; } void print_person( struct Person* p ) { printf( "%s %d" , (*p).name , (*p).age ) ; } void main() { struct Person data ; for( int i = 0 ; i < 10 ; i++ ) { read_person( &data ) ; print_person( &data ) ; } }
&((*p).age) | 式の部分のそれぞれの型 |
p | struct Personのポインタ |
*p | struct Personの構造体 |
(*p).age | int |
&((*p).age) | intへのポインタ |