2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」 西尾 信彦 nishio@cs.ritsumei.ac.jp 立命館大学情報理工学部 情報システム学科
配列 配列とは? 宣言の仕方 同一型の変数が(メモリ上に隣接して)並んだもの 配列のデータ型 配列名[配列の大きさ]; 例: int sample[4]; ⇒int型のデータの入る変数4個分を宣言 char name[32]; ⇒char型のデータの入る変数32個分を宣言
[]の中は0から始まる int sample[4]; と宣言すれば “[]”は添字演算子とも呼ばれる int sample[4]; と宣言すれば sample[0], sample[1], sample[2] ,sample[3]のint型のデータが格納できる4つの変数を宣言したことになる。
配列の例: 実行結果: #include <stdio.h> int main(){ int sample[4]; int i; for(i = 0; i < 4; i++){ sample[i] = i + 1; printf("sample[%d] = %d\n", i, sample[i]); } 実行結果: sample[0] = 1 sample[1] = 2 sample[2] = 3 sample[3] = 4
変数のチェック ~正しいプログラムを書くために~ コンパイラにできること コンパイラには配列は判断できない? だから気をつけないと 動かしてみないとわからないこと C言語はやってくれない だから気をつけないと!
ポインタ(というデータ)とは? 変数のメモリ上での位置を表わすデータ ポインタというデータの正体: ポインタデータの作り方 それが 指す変数が格納された メモリ上の先頭アドレスと 指す変数に格納されるデータのサイズによって表わす ポインタデータの作り方 そのポインタが指したい変数の頭に&をつける &は実は演算子(アドレス演算子)
しかし,このデータをどう使う? そのままでは代入くらいにしか使えない ポインタ変数の宣言の仕方(作り方) ポインタ演算 代入式の右辺と左辺 右はデータ,左は変数って気づいてた? ポインタ変数の宣言の仕方(作り方) データ型 *変数名; 例: int *value; ポインタ演算 ポインタの足し算,引き算
ポインタの例: 実行結果: #include <stdio.h> int main(void){ int data = 33; int *data_pointer; data_pointer = &data; /* dataのアドレスをdata_pointerに代入*/ printf("data = %d\n", data); printf("&data = %d (%x)\n", &data, &data); /* dataのアドレスを参照 */ printf("*data_pointer = %d\n", *data_pointer); /* アドレス先の値を参照 */ printf("data_pointer = %d (%x)\n", data_pointer, data_pointer); } 実行結果: data = 33 &data = 1245064 (12ff88) *data_pointer = 33 data_pointer = 1245064 (12ff88)
演算子と式 演算子は計算するためのもの 計算したら結果(答)が出る 例 四則演算(+-*/)は知ってますよね? 例 四則演算(+-*/)は知ってますよね? [数字] [演算子] [数字] と並べるけど [演算子] [数字] なんてのもある さらに数字は式でもいい 演算子には優先度があるので()が必要 計算したら結果(答)が出る 式を計算したら答が出る C言語では、「式を評価すると値が出る」という &も*も演算子 --も++も演算子 []も実は演算子 さらに””も=も演算子
&は変数を評価してその変数へのポインタを値とする *はその逆 *は中置演算子の場合は乗算 A * (B + C) *は前置演算子の場合はポインタの指す先 *A = *B * 2 ++と—は前置と後置ができる 評価した値が違うだけ 1加減した後の値と1加減する前の値 &は変数を評価してその変数へのポインタを値とする *はその逆 & [変数] ポインタ * [ポインタ] 変数
配列とポインタの関係 配列名はその配列の第0要素へのポインタ しかし, int array[100]; arrayは&(array[0])と同じ しかし, 配列名は変数ではないので代入できないことに注意 配列は各要素が隣接しているのを利用できるので便利
配列とポインタの例: #include <stdio.h> #define ARRAY_LENGTH 3 int main( ){ int intMemory[ARRAY_LENGTH]; int *pointer; int i; pointer = &intMemory[0]; // ポインタの初期値を配列の先頭アドレスに設定 for(i = 0; i < ARRAY_LENGTH; i++){ scanf("%d", pointer); // 整数の入力. pointer++; // ポインタを1 つずらす } printf("値: アドレス\n"); pointer = intMemory; // ポインタの初期値を配列の先頭アドレスに設定 printf("%d: %x\n", *pointer, pointer); pointer++;// ポインタを1 つずらす
実行結果: 32 56 78 値: アドレス 32: 12ff80 56: 12ff84 78: 12ff88
ところで... 変数はいつできて,いつなくなるのか? どこから参照できるのかも重要 ものによって違う 静的変数 ローカル変数 グローバル変数 動的変数 (未出,来週やります)