情報処理演習 第7回 11月12日 工学部6・7・8・9・10組 学籍番号末尾偶数 1 東北大学 大学院情報科学研究科 全 眞嬉 http://www.dais.is.tohoku.ac.jp/~jinhee/enshu-15.html 2 ポインタ 1.ポインタの基礎 →本日 2.数値データのポインタ →本日 3.文字データのポインタ →次回 メモリとアドレス 3 変数と配列 値を格納する方法について学んだ 格納した値は必要に応じてプログラムの中でいつで も呼び出し可能 格納された値はメモリに保存される メモリ コンピュータ上で数値や文字などの値を保存して置く 装置 アドレス メモリ上でどこに保存されているかを示す住所 変数に値を格納する 4 50 75 a[0][0] a[0][1] a[1][0] a[1][1] 100 x 25 3 変数に値を格納する = ロッカーに荷物を入れる ロッカーに荷物を入れる 5 ロッカーに荷物を入れる手順 空いているロッカーを探す 荷物を入れてカギを掛ける ロッカーの番号を覚える ロッカーから荷物を取り出す手順 番号でロッカーを探す カギで開けて荷物を取り出す ロッカー番号=メモリアドレス 6 ロッカーの番号は大切 効率的 番号が無ければ大量のロッカーから荷物を探すのは 大変 コンピュータでも同様 大量のデータが保存されているメモリから何の手が かりなしで必要な情報を取り出すのはできない アドレスを用いる ロッカー コンピュータ 番号 アドレス メモリに変数の値を格納する 7 値が格納される場所 アドレス番号が必要 メモリ 変数x x 100 データ型名 サイズ char 1バイト short 2バイト int、 long 4バイト float 4バイト double 8バイト 格納される場所 4バイト 変数のアドレス 8 メモリ上の何番のアド レスに変数が格納され ているか アドレス番号を気にす る必要は無い 変数のアドレスを確認 &変数名 アドレスを表示させる 変換指定子 %p /*ex22.c*/ #include<stdio.h> main() { int x=100; printf("x = %d¥n",x); printf("address : %p¥n",&x); } 変数のアドレス 9 int x=100; printf("x = %d¥n",x); printf("address : %p¥n",&x); 実行結果 x=100 address : ffbffc1c 変数xの値とメモリ上の 何番地に格納しているか を確認 ffbffc1c 16進数 1バイト 変数のサイズを確認(sizeof演算子) 10 int x=100; printf("x = %d¥n",x); printf("address : %p¥n",&x); printf("size : %d byte¥n",sizeof(x)); 実行結果 x=100 address : ffbffc1c size : 4byte データ型名 サイズ char 1バイト short 2バイト int、 long 4バイト float 4バイト double 8バイト sizeof 演算子 型や変数のバイト数を調べられる sizeof(変数名) sizeof(x) sizeof(型) sizeof(int) sizeof(double) 変数のアドレス 11 変数の値を変更し、 アドレスを確認 ex22.c を変更 xの値を200に変更 するプログラム 値を変更しても変数 のアドレスは変わら ない /*ex22.c*/ #include<stdio.h> main() { int x=100; printf("x = %d¥n",x); printf("address : %p¥n",&x); printf("size : %d byte¥n",sizeof(x)); x=200; printf("x = %d¥n",x); printf("address : %p¥n",&x); printf("size : %d byte¥n",sizeof(x)); } 変数のアドレス 12 int x=100; printf("x = %d¥n",x); printf("address : %p¥n",&x); printf("size : %d byte¥n",sizeof(x)); x=200; printf("x = %d¥n",x); printf("address : %p¥n",&x); printf("size : %d byte¥n",sizeof(x)); 実行結果 x=100 address : ffbffc1c size : 4byte x=200 address : ffbffc1c size : 4byte 値を変更しても変数xのメモリ上の格納場所 であるアドレスは変わらない 格納される値のみ変更される 配列のアドレス 13 実行結果 a[0]= 100, a[1]= 34, a[2]= 78, a[3]= 45, a[4]= 98, a[5]= 56, a[6]= 100, a[7]= 89, a[8]= 94, a[9]= 78, address : ffbffbf4 address : ffbffbf8 address : ffbffbfc address : ffbffc00 address : ffbffc04 address : ffbffc08 address : ffbffc0c address : ffbffc10 address : ffbffc14 address : ffbffc18 /*ex23.c*/ #include<stdio.h> main() { int i; int a[10]={100,34,78,45,98,56,100,89,94,78}; for(i=0;i<10;++i) printf(“a[%d]=%3d, address : %p¥n”,i,a[i],&a[i]); } 配列におけるメモリ上のアドレス 14 メモリ a[0]= 100, address : ffbffbf4 a[1]= 34, address : ffbffbf8 a[2]= 78, address : ffbffbfc a[3]= 45, address : ffbffc00 a[4]= 98, address : ffbffc04 a[5]= 56, address : ffbffc08 a[6]= 100, address : ffbffc0c a[7]= 89, address : ffbffc10 a[8]= 94, address : ffbffc14 a[9]= 78, address : ffbffc18 データ型名 サイズ char 1バイト short 2バイト int、 long 4バイト float 4バイト double 8バイト a[0] a[1] a[2] a[3] a[4] a[5] a[6] ・・・・ 4byte 4byte 4byte 4byte 4byte 4byte 4byte ポインタとは 15 変数の一種 アドレスを格納するための変数 ポインタと言う特殊の変数を用いることで、他の変 数たちが持つアドレスを格納することが可能 100 x 変数xの アドレス ffbffc1c ポインタ アドレスを格納できる変数 ポインタの変数の宣言 16 宣言方法 他の変数と同様ポインタ変数の宣言を行う 変数の名前の前に「*」を付ける 型名 *変数名; int *p1; float *p2; char *p3; 宣言により変数 p1,p2,p3のポインタ変数が用意される 「*」はポインタ宣言時には付けるが、ポインタ名には「*」 を付けないので注意 ポインタの宣言と変数の宣言 17 ポインタ変数を宣言する際には必ず「*」を付ける ポインタの宣言 int *a; int b; 変数の宣言 ポインタの変数の宣言 18 ポインタを宣言する際に変数の型名を 指定 int型ポインタ、int*型 int *p1; float型ポインタ、flaot*型 float *p2; char *p3; char型ポインタ、char*型 ポインタの型 19 変数のアドレスはその 変数の型に対応した ポインタ変数にしか格 納できない int型のポインタであるint* 型のポインタ変数のみに そのアドレスの格納可能 100 int 型 x ffbffc1c ○ int *型 変数xの アドレス × float*型 ポインタを使うメリット 20 C言語でポインタを用いると 関数などで変数のアドレスを引数として渡すことがで きる 文字列や配列をより便利に利用できる その他の型を含めた動的なデータ構造を定義できる ポインタへのアドレス代入 21 /*ex24.c*/ #include<stdio.h> main() { int x; int *p; p=&x; printf("address of x : %p¥n",&x); printf("pointer p : %p¥n",p); } 実行結果 address of x : ffbffc18 pointer p : ffbffc18 普通の変数か ポインタ変数か によって記述す べき内容が異 なる &x はxのアドレ ス、&演算子を 利用した計算式 p はxのアドレス を格納している ポインタ変数 ポインタから変数の値を参照 22 ポインタに格納されているアドレスから、そこに格納 されている変数の値を取得 間接参照演算子 * *ポインタ変数名; ポインタ側からある変数に格納されている値を調べる ex24.c を変更 下記を追加 x=100; printf(“value of x : %d¥n",x); printf("value of p : %d¥n",*p); 実行結果 address of x : ffbffc18 pointer p : ffbffc18 value of x : 100 value of p : 100 &演算子と*演算子と各変数の対応 23 &演算子 変数が格納されているアドレスを返す演算子 *演算子 ポインタからそのアドレスに格納されている値を返す演算子 /*ex24.c*/ #include<stdio.h> main() { int x; int *p; p=&x; printf("address of x : %p¥n",&x); printf("pointer p : %p¥n",p); x=100; printf(“value of x : %d¥n",x); printf("value of p : %d¥n",*p); } x 変数xの値 &x 変数xが格納されているア ドレス p 変数xのアドレスが格納さ れているポインタ &xのアドレス と同じ *p ポインタpが指すアドレスに xの値と同じ 格納されている変数の値 配列要素とアドレス 24 b[0]= 36.5 b[1]=38.4 b[2]=37.5 メモリ b[0] b[1] b[2] 4byte 4byte 4byte データ型名 サイズ char 1バイト short 2バイト int、 long 4バイト float 4バイト double 8バイト 配列要素とアドレス 25 配列でのアドレス 配列の要素の前に&を付けると値が格納されているアドレ スが分かる 配列名の演算によって各配列要素のアドレスを取得でき る &b[0],&b[1],&b[2] b+1,b+2 配列のアドレスを求める方法 &を使う方法 配列名で指定する方法 &b[0] &b[1] &b[2] b b+1 b+2 b[0]= 36.5 b[1]=38.4 b[2]=37.5 配列要素とアドレス 26 /*ex25.c*/ #include<stdio.h> main() { float b[3]={36.5, 38.4, 37.5}; printf("address of b[0]: %p, b : %p¥n",&b[0], b); printf("address of b[1]: %p, (b+1): %p¥n",&b[1], (b+1)); printf("address of b[2]: %p, (b+2): %p¥n",&b[2], (b+2)); } 実行結果 address of b[0]: ffbffc14, b : ffbffc14 address of b[1]: ffbffc18, (b+1): ffbffc18 address of b[2]: ffbffc1c, (b+2): ffbffc1c 配列のアドレスから値を調べる 27 変数の場合と同様に配列要素に関してもアドレス 情報から格納されている値を取得可能 間接演算子*を利用 *b *(b+1) *(b+2) 注意 0番地以外は()を忘れずに付ける *(b+1) *b+1 配列のアドレスから各配列要素の値を参照 28 /*ex26.c*/ #include<stdio.h> main() { int i; float b[3]={36.5, 38.4, 37.5}; for(i=0;i<3;++i) printf("value of b[%d]: %3.1f, value of *(b+%d): %3.1f¥n",i,b[i],i, *(b+i)); } 実行結果 value of b[0]: 36.5, value of *(b+0): 36.5 value of b[1]: 38.4, value of *(b+1): 38.4 value of b[2]: 37.5, value of *(b+2): 37.5 配列における記述法の比較(先頭要素の場合) 29 配列要素での指定 値 b[0] アドレス &b[0] 配列名での指定 *b b ポインタはアドレスを指し示すための変数 配列bに関してはbと記述することで配列が確保してい るメモリの中の先頭のアドレスを取得できる つまり、bは配列の先頭要素のアドレスが格納されてい るポインタ変数でもある 演習1 30 /*ex27.c*/ /*学籍番号: 名前: */ /*ポインタが指す変数の値の表示*/ #include<stdio.h> main() { int i=10; int *p; /*int型変数を指すポインタpの宣言*/ p=&i; /*ポインタpに変数iのアドレスを代入*/ printf("%d ¥n",*p); /*ポインタpの指す変数の値を表示*/ *p=10*(*p); /*ポインタpの指す変数の値を10倍にする*/ printf("%d ¥n",*p); /*ポインタpの指す変数の値を表示*/ } 実行結果 10 100 演習2 31 /*ex28.c*/ /*学籍番号: 名前: */ /*ポインタが指す変数の計算*/ #include<stdio.h> main() { int a=10; int b=5; int c; int *pa ; /*aへのポインタpaを宣言*/ int *pb ; /*bへのポインタpbを宣言*/ pa= &a ; /*アドレス演算子によりaのアドレスをpaに代入*/ pb= &b ; /*アドレス演算子によりbのアドレスをpbに代入*/ c=*pa + *pb; printf("a+b=%d¥n",c); } 実行結果 a+b=15
© Copyright 2024 ExpyDoc