プログラミング初級 第 7 回 2017 年 5 月 29 日 配列 ( 復習 )~ 文字列 1
配列とは 2 配列 : 複数の変数をグループとしてまとめて扱うもの 配列 変数 int data[10]; 整数型の配列 同種のデータ型を連続して確保したものを配列とよぶ = 整数がそれぞれにひとつずつ入る箱を 10 個用意したようなもの int data; 整数型の変数 = 整数がひとつ入る dataという名前の箱を用意したようなもの data[0] data[2] data[4] data[6] data[8] data[1] data[3] data[5] data[7] data[9] data
配列を扱うときの注意 3 配列の要素番号は 0 から始まることに注意せよ! 配列 int data[10]; 整数型の配列 配列の大きさは宣言のときに書く 同種のデータ型を連続して確保したものを配列とよぶ = 整数がそれぞれにひとつずつ入る箱を 10 個用意したようなもの data[0] data[2] data[4] data[6] data[8] data[1] data[3] data[5] data[7] data[9]
例題 1 int 型配列 dat( 要素数 4) に 100,200,300,400 を代入し それらの合計を求めるプログラムを作成せよ int i, goukei = 0, dat[4] = 100, 200, 300, 400; for 文を使う例 4 for ( ; ; ) goukei = printf("4 つの値の合計は %d です n", goukei); int i = 0, goukei = 0, dat[4] = 100, 200, 300, 400; while ( ) goukei = i printf("4 つの値の合計は %d です n", goukei); while 文を使う例
例題 2 次のプログラムには重大な間違いが含まれている どこに問題があるか指摘せよ 5 int i, InfProd = 1, data[4]; for (i=0; i<10; i++) scanf("%d", &data[i]); for (i=0; i<10; i++) InfProd = InfProd * data[i]; printf(" 入力された 10 個の値の総乗は %d です n", InfProd); data[0] data[2] data[1] data[3] 分からない人へのヒント 最初の for 文が何をしているか考えてみよう 適当に整数データを入力した状況を想定し そのデータが配列にどのように格納されるか図化してみよう
例題 3 ユーザーからの数値入力を 3 つ受け付け それらの合計と平均値を求めるプログラムを作成せよ なお ユーザーが入力する数値は整数とし 入力された数値は配列 seisu に入るものとする 6 int i, goukei = 0, seisu[3]; double average; // 数値入力を受け付ける for (i=0; i<3; i++) printf(" 整数 %d を入力してください >>,i); scanf( ); // 合計を計算する for (i=0; i<3; i++) goukei = average = ( )goukei / 3.0; printf(" 合計は %d 平均は %f です n", goukei, average);
例題 4 int 型配列 dat( 要素数 10) に入っている整数値の最大値を求めるプログラムを完成させよ 7 int i, max, dat[10] = 5,7,2,8,3,1,9,0,4,6;//max は最大値を入れるための変数 max = dat[0]; // とりあえず dat[0] の値を仮の最大値とする for (i=1; i<10; i++) //1 番目の値と順次比較し 大きければ仮の最大値を入れ替える if (dat[i] ) max = printf(" 最大値は %dです n", max);
例題 5 次のプログラムを読んで どんな結果が得られるプログラムであるかを読み解け 8 int i, tmp, data[10] = 5,7,2,8,3,1,9,0,4,6; for (i=1; i<10; i++) if (data[i] > data[0]) tmp = data[0]; data[0] = data[i]; data[i] = tmp; printf(" 最大値は %d です n", data[0]); a = 10, b = 5 を例に考えてみよう x = a; //x の値は a = b; //a の値は b = x; //b の値は ここで a =, b = になった つまり 何をしたことになる? data[0] data[2] data[4] data[6] data[8] data[1] data[3] data[5] data[7] data[9]
練習問題 問 1 例題 4 を改変し 最小値を求めるプログラムを作成せよ問 2 ユーザーが入力した 10 個の整数値を配列 dat に格納する それを用いて最大値と最小値を表示するプログラムを作成せよ 問 3 ユーザーが入力した 10 個の整数値を配列 dat に格納する それを用いて最大値と最小値を求めよ さらに それぞれ何番目に入力されたものであるかも表示せよ 問 4 負の数を入力されるまで任意の個数の整数値 ( 最大 100 個 ) の入力を受け付ける その入力に基づいて前問と同様の結果を表示するプログラムを作成せよ 問 2 の実行例 問 3 の実行例 問 4 の実行例
問 5 次のプログラムを読んで 右の表を埋めながら どんな結果が得られるプログラムであるかを読み解け int i, j, tmp, data[5] = 5,7,2,8,3; i j 0 10 data [0][1][2][3][4] 5 7 2 8 3 for (i=0; i<4; i++) for (j=i+1; j<5; j++) if (data[j] > data[i]) tmp = data[i]; data[i] = data[j]; data[j] = tmp; 例題 5 を参照のこと //for (i=0; i<5; i++) // printf("%d ",data[i]); // //printf(" n"); 10
文字列は 文字型変数の配列 11 文字列とは 文字型で定義される変数の配列 のことである (C 言語では文字列を 1 文字の集まり という扱いになる ) // 文字列に関するプログラム char moji[20] = "TohokuGakuinUniv."; < 実行結果 > TGU printf("%c", moji[0]); printf("%c", moji[6]); printf("%c", moji[12]); printf(" n"); T o h o k u G a k u i n U n i v. 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9][10][11][12][13][14][15][16][17][18][19]
教科書 p.79 12 gets(s); の代わりに scanf("%s", s); も使える ( 空白が使えない : 教科書 p.81 参照 ) puts(s); の代わりに printf("%s n",s); も使える 12
// 文字列に関するプログラム char namae[10]; 13 scanf("%s", namae); // もしくは gets(namae); ringo と入力すると? banana と入力すると? orangejuice と入力すると?
文字列に関する留意事項 14 文字列の最後には 0( ヌル文字 ) が存在する C 言語は文字列の最後に 0( ヌル [NULL] 文字という ) が付くルールになっている ( 0 までを文字列と判断している ) 十分な配列長を確保すること 用意した配列の大きさを超えるデータを入力するとプログラムは異常終了や暴走を起こす可能性がある # 最低でも 必要データ数 +1 個 の配列を用意すること
配布プリント p.120 のリスト 8.3 15 // ヌル文字 0 を付け加えています char namae1[6] = 'r', 'i', 'n', 'g', 'o', ' 0'; char namae2[5] = 'k', 'a', 'k', 'i', ' 0'; int i; for(i = 0; namae1[i]!= ' 0'; i++) printf("%c", namae1[i]); printf(" です n"); for(i = 0; namae2[i]!= ' 0'; i++) printf("%c", namae2[i]); printf(" です n"); //ringo を表示 for 文でも while 文のような書き方ができる ( リスト 8.6 も参照のこと ) // kaki を表示
配布プリント p.124 の内容を確認 16 < 留意点 1> 初期化をしない文字列には何が入っているか不定である char hairetsu[10]; これは 10 文字分の文字列は確保したが ゴミ ( 変な値 ) が入っている可能性大 char hairetsu[10] = ""; char hairetsu[10] = ' 0'; これは 10 文字分の文字列を確保 + 何も値が入っていないことが保証される < 留意点 2> 文字列の初期化には 文字列ラテラル として一括初期化 一文字ずつ代入して初期化の 2 通りがある char hairetsu[6] = "TOKYO"; これは hairetsu に TOKYO という文字列 +NULL 文字が代入される Char hairetsu[6] = 'T','O','K','Y','O',' 0'; これは一文字ずつ代入している NULL 文字もプログラムの中で必ず記述する必要がある < 留意点 3> 自動的に文字列の長さが決まる書き方がある char hairetsu[] = "innovation"; 要素数が自動的に決まる ( 文字数 +1(NULL 文字 ))
例題 6 このプログラムの実行結果を予想せよ ( 分からないときは図に書き込みながら考えてみよう あるいは配布資料の p.132 をよく読もう ) 17 char namae[10] = "TGyniv."; // 配列の初期化 namae[2] = 'U'; namae[3] = ' 0'; //2 番目の要素を変更 //3 番目の要素を変更 printf(" 文字列は %s です n", namae); T G y n i v. 0
文字列も単なるデータ列 18 < ポイント > 文字列に対して 文字単位での一致 不一致を簡単にチェックできる char moji[20] = "ABACCDEAAFDDECCBAED"; int i, counta = 0; for (i=0; i<20; i++) if (moji[i] == 'A') counta = counta + 1; < 実行結果 > ABACCDEAAFDDECCBAED この文字列内に A を 5 個検出 printf("%s n", moji); printf(" この文字列内に A を %d 個検出 ", counta); printf(" n");
例題 7 入力した文字列の文字数を数えるプログラムを完成させよ 19 //while 文で書く例 char str[100]; int count = 0; gets(str); //str 配列の count 番目の文字が //NULL 文字でない間は count を増やす while (str[ ] ) //for 文 +break 文で書く例 char str[100]; int count; gets(str); //str 配列の count 番目の文字が //NULL 文字ならループから抜け出す for (count=0; count<100; count++) printf(" 文字数は %d です n", count); printf(" 文字数は %d です n", count); < 実行例 > TohokuGakuinUniversity 文字数は 22 です
例題 8 入力した文字列に対し ピリオドが出てくるまで一文字ずつ表示するプログラムを完成させよ 20 char str[100]; int count; printf(" 文字列を入力してください >>"); gets(str); //str 配列の count 番目の文字が //. ならループから抜け出す for (count=0; count<100; count++) printf printf(" n"); < 実行例 > 文字列を入力してください >>Gakuin.Taro Gakuin
例題 9 文字列 moji に含まれる A の個数 それ以外の文字の個数を数えるプログラムを以下に示す switch~case 文の使い方を確認の上 以下のプログラムの動きを理解せよ 21 char moji[20] = "ABACCDEAAFDDECCBAED"; int i, counta = 0, countetc = 0; for (i=0; i<20; i++) switch (moji[i]) case 'A': counta = counta + 1; break; default: countetc = countetc + 1; switch~case 文の使い方を思い出すこと こういう使い方もできる printf("%s n", moji); printf(" この文字列内に A を %d 個検出 n", counta); printf(" それ以外の文字を %d 個検出 n", countetc); < 実行例 > ABACCDEAAFDDECCBAED この文字列内に A を 5 個検出それ以外の文字を 15 個検出
練習問題 問 6 名前と苗字の間にスペースを入れて氏名を入力すると ( 例 :Taro Gakuin) と こんにちは xx さん と名前だけが表示されるプログラムを作成せよ ( ヒントは例題 8) 問 7 例題 9 を改変し A の個数 B の個数 C の個数 それ以外の文字の個数を表示するプログラムを作成せよ 問 8 2 つの文字列 ( いずれも最大 20 文字 (NULL 文字含む )) を入力する それらが完全に一致する場合は 同じ文字列です そうでない場合は 異なる文字列です と表示するプログラムを完成させよ 問 6 の実行例 名前を入力してください >>Taro Gakuin こんにちは Taro さん 問 7 の実行例 ABACCDEAAFDDECCBAED この文字列内に A を 5 個検出この文字列内に B を 2 個検出この文字列内に C を 4 個検出それ以外の文字を 9 個検出 問 8 基本プログラム char str1[20] = "", str2[20] = ""; int i, match = 1; printf(" 文字列 1 を入力してください >"); gets(str1); printf(" 文字列 2 を入力してください >"); gets(str2); for (i=0; i<20; i++) // 文字列を初期化 問 8 の実行例 文字列 1 を入力してください >Gakuin 文字列 2 を入力してください >Tohoku 異なる文字列です if (match!= 1) printf(" 異なる文字列です n"); else printf(" 同じ文字列です n");
問 9 文字配列 str( 最大 100 文字 ) に任意の文字列を入力する その文字列において B の次に A が来ている回数をカウントするプログラムを作成せよ ( 実行例を参照すること ) < 実行例 1> 文字列を入力せよ >ABCDBABADCBABBA 文字列 ABCDBABADCBABBA において BA が含まれる回数は 4 回です < 実行例 2> 文字列を入力せよ >BABACBA 文字列 BABACBA において BA が含まれる回数は 3 回です < 実行例 3> 文字列を入力せよ >ABCDEFG 文字列 ABCDEFG において BA が含まれる回数は 0 回です 23
問 10 文字列 1( 最大 100 文字 ) 文字列 2( 最大 50 文字 ) それぞれに文字列を入力すると 文字列 2 の内容が文字列 1 に連結されるプログラムを作成せよ ( 具体例 ) str1 に Tohoku が入力され str2 に Gakuin が入力されたとき str1 が TohokuGakuin となるようにする 問 10 基本プログラム char str1[100] = ' 0', str2[50] = ' 0'; int i, length1 = 0, length2 = 0; printf(" 文字列 1 を入力してください >"); gets(str1); printf(" 文字列 2 を入力してください >"); gets(str2); printf(" 連結した結果 str1 は次のようになりました n"); printf("%s n", str1); < 実行例 > 文字列 1を入力してください>Tohoku 文字列 2を入力してください>Gakuin 連結した結果 str1は次のようになりました 24 TohokuGakuin
int i, j, tmp, data[5] = 5,7,2,8,3; for (i=0; i<4; i++) for (j=i+1; j<5; j++) if (data[j] > data[i]) tmp = data[i]; data[i] = data[j]; data[j] = tmp; //for (i=0; i<5; i++) // printf("%d ", data[i]); // //printf(" n"); i j data [0][1][2][3][4] 5 7 2 8 3 0 1 7 5 2 8 3 0 2 7 5 2 8 3 0 3 8 5 2 7 3 0 4 8 5 2 7 3 1 2 8 5 2 7 3 1 3 8 7 2 5 3 1 4 8 7 2 5 3 2 3 8 7 5 2 3 2 4 8 7 5 2 3 3 4 8 7 5 3 2