オブジェクト指向言語論 第六回 知能情報学部 新田直也 配列の宣言 配列:任意にアクセスできる変数の列. a[0] a[1] a[2] a[3] a[4] … 配列名と添字 a[3] 配列名 添字 (C, C++, Javaの場合,先頭は0番) 配列宣言 int a[1000]; 使用する要素数 配列宣言(Java, VB) Javaの配列宣言 int[] a = new int[1000]; VBの配列宣言 Dim a(1000) as Integer 多次元配列 たとえば表のデータを扱う場合(2次元配列). a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] 多次元配列の宣言 int a[3][4]; 12個のint型の要素が用意される. 配列とメモリ 配列の要素はメモリ上に連続して配置される. : 0xffff番地 a[3] b[1][0] a[2] b[0][2] a[1] a a[0] 0xffff番地 b[1] b[0][1] b, b[0] b[0][0] 0x0000番地 : 0x0000番地 配列名で先頭アドレスを参照することもできる (参照のみで代入はできない). スタック領域の詳細 関数呼出しに応じて スタック領域が確保される. main () { int x = 1; x = input(x); } int input(int y) { char s[10]; scanf(“%s”, s); printf("%s\n", s); return y + 1; } 0xffff番地 main用 x : y 戻り番地 : s[1] s[0] 引数用 20バイト input用 自動変数用 28バイト 0x0000番地 バッファオーバーフロー攻撃 scanfなどで戻り番地を上書きする. 戻り番地は29~32文字目 main () { int x = 1; x = input(x); } int input(int y) { char s[10]; scanf(“%s”, s); printf("%s\n", s); return y + 1; } 0xffff番地 main用 x : y 戻り番地 : 不正な s[1] コード s[0] 引数用 20バイト input用 自動変数用 28バイト 0x0000番地 1次元配列の引数渡し 配列名は配列の先頭アドレス. main() { int a[100]; : func(a); : } void func(int x[]) { 受け側は要素数を指定しない. int *x で受けても良い. いずれにせよサイズがわからな いので注意. 2次元配列の引数渡し 配列名は配列の先頭アドレス. main() { int a[100][10]; : func(a); : } : 0xffff番地 a[1][0] a[0][9] : a[0][1] int が 10 個分 a[0][0] 0x0000番地 void func(int x[][10]) { 受け側は最高次元の要素数を 指定しない. ポインタ ポインタをURL,ポインタが指す先をWebページと 考えてみる. アドレスが指す先の内容 int *p; アドレス p は指す先が int 型であるポインタ *p p http://www.hogehoge.com <html> <body> <H1>5</H1> </body> </html> ポインタの更新と参照先の更新 p の値の変更と *p の値の変更の違い. *p = 7; → Webページの更新 *p p http://www.hogehoge.com http://www.hogehoge2.com *p p = q; → リンク先の変更 7 7 <html> <body> <H1>5</H1> 7 </body> </html> アドレスの取得 配列の先頭アドレス: int a[1000]; と宣言したときの a (配列名) 変数のアドレス: int x; アドレス 内容 と宣言したときの &x ポインタを用いた値の共有 以下のプログラムを実行してみる. 内容 int x; int *p; アドレス p = &x; このとき x の値も同時に 3 になる *p = 3; 値呼出しと参照呼出し 値呼出し: 関数に実引数の値を渡すが,呼出しによって実引数の値が 変更されることはない. 12 : 12 12 x func(a); a : void func(int x) { 参照呼出し: : 関数に実引数の参照(ポインタ)を渡す.関数内部で実引数 の値が変更することが可能である. : 12 func(&a); a : void func(int *x) { 参照渡し(2) 厳密には参照渡しも値渡しの一種である. 14 12 a 1536 1536 : func(&a); &a = 1536 : x void func(int *x) { : *x = 14;
© Copyright 2024 ExpyDoc