Comments
Description
Transcript
ユニット演習I(7回目)
ユニット演習 I(7回目) 配列 例えば,100 件のデータがあったとき,これを入れるための変数として,a0, a1, a2, ... と いった単純変数を用いたのでは大変なことは明らかです.そこで,何件ものデータを総括的に扱う ためのデータ構造として配列というものが用意されています.配列はデータの総数を表す配列名と 何件目のデータかを示す添字とで管理され,添字は [ ] で囲まれます.添字が 1 つからなる配列を 一次元配列と呼びます. C言語において,例えば整数型の 100 件のデータを入れる配列を宣言するには, int a[100]; とします.これにより, a[0], a[1], ... , a[99] という 100 個の配列要素が用意されます. BASIC のように a[0], a[1], ... , a[100] までの 101 個ではありません.ですから, a[100]=777; などとすると,とんでもないアドレスに強引に書き込むことになり,暴走につながる可能性があ ります. (もしそのアドレスに別の変数が割り当てられていれば,そのデータは破壊されてしまい ます. ) C言語における配列の宣言は次のように行います. 型 配列名 [要素数][要素数]...; 型は int 型以外にも,char 型,double 型などの全ての型(void 型,関数型を除く)を指定する ことができます.[ ] が 1 つのものを一次元配列,[ ] が 2 つのものを二次元配列,…と呼びます. 指定する〈要素数〉は添字の上限ではなく,要素 0 から始まる配列要素の数であることに注意して 下さい. 配列の宣言時に指定する [ ] は値が定まっている定数または式しか書けませんが,配列を参照 する場合の [ ] には変数も書くことができます.このことは配列の添字をプログラム上で操作で きることを意味します.単純変数 a0, a1, a2, ... の 0 や 1 は変数名の一部であるため,プログ ラムで操作できるようなものではありません. 配列 a[ ] の i 番目の要素は a[i] と表すことができます.このとき a を配列名,i を添字,a[i] を配列要素と呼びます.さて,int 型の配列 a[ ] のデータを全て 0 に初期設定するには,次のよ うに行います. 34 配列の宣言と初期化 (1) int a[10]; for(i=0 ; i<10 ; i++){ a[i]=0; } 配列の宣言と初期化 (2) int a[]={0,0,0,0,0,0,0,0,0,0}; /* または, int a[10]={0,0,0,0,0,0,0,0,0,0}; でも OK! */ 配列を初期化する場合には,もちろん,a[0], a[1], ... にそれぞれ値を代入する式を書けば } を用いて,初期値リストを書いてやります.右上記の例では 配列 a の各要素に 0 という数値が初期設定されます.配列の長さを示す添字は省略できます.その よいのです.しかし,普通は { )これが可能なのは,初期値要素 ときは合理的な値が自動的に設定されます. (上記では 10 である. の数を調べることにより,その配列長をコンパイラが知ることができるからです.この配列の初期 化は他のデータ型の時も同様です.例えば, 配列の宣言と初期化 (3) double d[]={100.0, 100.1, 100.2, 100.3, 100.4}; char 型配列による文字列の表現 C言語には文字列を表現する型というものはありません. (string 型はない. )文字列を表すには char 型の配列を用います. では,はじめに文字列がどのように内部表現されているかを説明しておきましょう.BASIC で は文字列変数は長さ情報を持っていますが,C言語の文字列表現のルールはもっと単純になってい ます.それは, 「文字列の最後に文字コード 0 を付加する」ということです.だから,C言語では文 字列 ABC はメモリ上に次のように置かれています. ’A’ ’B’ ’C’ \0 この\0 は文字列の終端を知るための重要なコードです.このような構造のためC言語では文字列 処理のときに, 「コードが\0 になるまで何かの処理をする」という方法が用いられます. それでは,実際に char 型配列に文字を入れてみましょう.ここでは,文字配列の初期化につい て説明します.char 型配列の設定には 2 つの方法があります.まず,基本の通りに, 35 文字配列の初期化 (1) char char /* 直接数値を書く */ s[10]={65,66,67,68}; /* 文字定数を書く */ ss[10]={’A’,’B’,’C’,’D’}; のように設定することができます.char 型配列を使って文字列を格納するときは,十分な長さの 配列を確保するようにしましょう.そうしないと,暴走を起こします.例で使われている文字列は ABCD という 4 文字ですが,内部的には終端に文字コード\0 があるため,5 文字になっています. 文字配列 ss の内部表現を下に示します. ss[0] ss[1] ss[2] ss[3] ss[4] ’A’ ’B’ ’C’ ’D’ \0 ss[5] ss[6] ss[7] ss[8] ss[9] 現実には char 型配列は文字列表現に多用され,その度に’ ’ で文字を囲むことはとても大変で す.そこでこれとは別に文字列専用の初期化方法が用意されています.それは次のように行われ ます. 文字配列の初期化 (2) この場合も配列の余った部分には\0 が詰められ ます.また配列の長さを示す添字は省略できま char char す.その場合は適切な配列を確保してくれます. char e[]="jindai"; char と記述すると, char s[10]="jindai"; ss[10]="神大"; 文字配列の表示 例えば e[7]="jindai"; s[10]="jindai"; for(i=0 ; i<7 ; i++) として処理されます. printf("%c",s[i]); この場合,文字列 jindai と終了コード\0 を 格納するために必要な配列長は 7 なので,e[7] printf("%s\n",s); が確保されるのです. 文字列の場合は長さを数えるのが面倒なので,添字を省略する方が便利です. 文字列の表示方法は,for 文でループ変数を用いて文字配列の各要素を出力する方法(この時, 書式制御文字は%c)と,printf 文で書式制御文字「%s」を用いて,変数の指定は [ ] なしの文字配 列名で行う方法があります. 36 実習:Cプログラム 以下のプログラムを作成して下さい. (下線部には適当なコメントを入れましょう. ) また,適当なデータを入力して実行結果を確かめなさい. プログラム(ex07.c) /* /* /* /* <File Name> <Affiliation> <Name> <Date> */ ________.c 電子情報フロンティア学科 _年_組_________番 */ __________ */ 2009 年__月__日 */ #include <stdio.h> #define N 10 int main(void); /* データ数 */ /* プロトタイプ宣言 */ int main(void) { int i, j, k, buf, min, dummy, s[N]; /* データの入力 */ printf("%d 個の数を入力して下さい.\n",N); for(i=0 ; i<N ; i++) scanf("%d",&s[i]); /* ソートされる前のデータの出力 (入力順) */ printf("\n 入力データ: "); for(i=0 ; i<N ; i++) printf("%d ",s[i]); printf("\n"); /* データのソート (小さい順に) */ for(j=0 ; j<N-1 ; j++){ min = s[j]; buf = j; for(k=j+1 ; k<N ; k++){ if(s[k] < min){ min = s[k]; buf = k; } } dummy = s[j]; s[j] = s[buf]; s[buf] = dummy; } /* ソート後のデータの出力 */ printf("ソート結果: "); for(i=0 ; i<N ; i++) printf("%d ",s[i]); printf("\n"); return(0); } 37 授業中提出用問題(mon07.c) 5 個の整数データを入力して,入力した順および入力と逆順に出力するプログラムを 作成しなさい. プログラムの実行例 % ./a.exe 5 個の整数を入力して下さい. ==> 35 88 12 7 56 《入力した順に出力します. 》 35 88 12 7 56 《入力と逆順に出力します. 》 56 7 12 88 35 % 課題 10 個の整数データを入力して,総和,平均値,最大値,最小値,分散および標準偏差を求める ) プログラムを作成しなさい. (ファイル名は,kadai07.c とする. 38