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