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