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