ポインタとポインタを用いた関数定義 Quiz Q1. int main(void) { int a=1, b=0; { int a=2; b=b+a; } b=a+b; Q2. int main(void) { int a, b=0; for(a=0;a<2;a++){ static int b=0; b=a+b; } printf(“%d\n”,b); printf(“%d\n”,b); } } 前回の復習 • 関数の定義 • 変数の有効範囲 • 関数の再帰的定義と再帰呼び出し 変数の属性 名前 値 アド レ ス ( 値の格納場所) 変数 型( 格納領域の大き さ : バイ ト 数) 記憶のク ラ ス 有効範囲 例 8bit = 1byte(バイト) 0000H main(){ int a; ① 0001H 0002H 0003H a = 33; /* 33(10) =0021(16) */ ② a: 0 0 1 0 0 0 0 1 0004H 2バイト 0 0 0 0 0 0 0 0 (sizeof演算子で入手) ① aのアドレスが決まる(例の場合は0004H) メモリ ② アドレス0004に33に相当する値が格納される (auto変数のアドレスは関数呼び出し時に、static変数はプログラム実行時に決定) ポインタ変数とアドレス計算 • アドレス演算子&を用いる 前の例では&aは0004Hとなる。 アドレスを陽に記憶するためにはアドレスを値として格納す る変数が必要! ポインタ型変数:アドレスを値として持つ変数 なぜア ド レ ス 型変数と 呼ばないか? ア ド レ ス ポイ ン タ = 型の情報( 型に対する データ サイ ズの 情報) ポインタ変数の宣言と使い方 ・型名 *変数名{,*変数名;} int a; int* p; /* int *p; */ p=& a; (p 0004H) p++; (p 0006H) /* p 0005H*/ /* p = p + sizeof(int) */ 注意: 配列名は配列の最初の要素が 格納されているアドレスであり、 ポインタ型の定数である。 Int data[10], *p; p=data; 間接参照演算子* • ポインタ変数の「値」が指すアドレスの中身を取り出したり、逆に格納する ための演算子。 変数の名前を用いずに変数の値を使うことが可能に! ② ① int main(){ a: int a; int* p; 0 2 0004H 0 1 0005H 0006H p: int b; a=258; /* 258(10) =0102H*/ ① p=1; ④ printf("% d % d \n", a, b); } p: 0007H 0008H b: 0 2 0004H 0 1 0005H 0 4 0006H 0 0 0007H 0008H b: 0009H 0009H 変数名aを使わずに値が使われた,変更された! p=&a; ② b= p; ③ a: ④ ③ a: 0 1 0004H a: 変数のアドレスを使うことにより、明示的に 0 2 0004H 0 0 0005H 変数名を使わずに値を参照したり、変更できる。 0 1 0005H p: b: 0 4 0006H 0 0 0007H 0 2 0008H 0 1 0009H p: b: 0 4 0006H 0 0 0007H 0 2 0008H 0 1 0009H 配列とポインタ main(){ int data[3], p; ① p = data; ② (p+1) = 2; /* data[1]=2; */ ③ ② ① ③ 0009H 0009H data[0]: data[1]: p: 000AH 000AH data[0]: 0009H 000AH data[0]: 000BH 000BH 000CH 000CH 000DH 000DH 000EH 000EH 000EH 000FH 000FH 000FH 0010H 0011H p: 0 A 0010H 0 0 0011H 000BH data[1]: p: 0 2 000CH 0 0 000DH 0 A 0010H 0 0 0011H ポインタ変数を用いた関数定義(1) • ポインタ変数を用いる理由 1. 関数を呼び出して関数の値として結果を返すと、 1つの値しか返せない 2. 値を渡さないでそのあり場所(アドレス)を渡した 方が処理が速い場合がある 3. 関数を一度だけ呼び出して、呼び出し側の変数 の値を複数個変更できる その他の方法 ① 大域変数を使う(バグの元) ② 配列を使う(同じ型の結果のみ) 関数に2つアドレスを渡して値をコピーするプログラム main(){ a: int a=2,b; equal(&b,&a); b: 0 2 0004H p1: 0 6 0004H 0 0 0005H 0 0 0005H 0 2 0006H 4 0006H 0 0 0007H p2: 0 0 0 0007H } void equal(int* p1, int* p2) { 0008H 0008H 0009H 0009H *p1=*p2; } *p1=*p2 → *p1=2 → *(0006)=2 ポインタ変数を用いた関数定義(1) 2つの整数の和と積を1つの関数を呼び出すだけで計算する 大域変数の使用 int a,b,c,d; 配列の使用 main(){ ポインタの使用 main(){ int data[4]; int a, b, c, d; a = 1; data[0] = 1; a = 1; b = 2; data[1] = 2; b = 2; addmul(data); addmul(a, b, &c, &d); main(){ addmul(); void addmul() { c = a + b; void addmul(int x[]) void addmul(int x, int y, int p1, int p2) { { d = a * b; } } x[2] = x[0] + x[1]; p1 = x + y; x[3] = x[0]*x[1]; p2 = x y; }
© Copyright 2024 ExpyDoc