プログラミング基礎演習

鹿児島大学
プログラミング基礎演習
第9回
配列と文字列
半田利弘
鹿児島大学 大学院理工学研究科 物理・宇宙専攻
理化学研究所
配列とは…
▶ 同じ型の変数の組
■
■
順番が付いている
個数制限はint型整数の上限値まで
▶ C言語での表現方法
■
配列の各要素 aa[0], aa[1], aa[2],…
 番号は0から始まることに注意!
■
配列全体 aa
理化学研究所
平均点の計算
 List9-1(教科書p.207)
#include <stdio.h>
int main(void);
int main(void)
{
int hatoyama, kan, noda;
float heikin;
hatoyama=65;
小数点第1位までで四捨五入して書く
kan=90;
noda=75;
heikin=(hatoyama+kan+noda)/3.0;
printf("鳩山%d点\n菅%d点\n野田%d点", hatoyama, kan, noda); 理化学研究所
printf("平均は%.1f点\n",heikin);
return(0);
}
数が少ないならよいが…
▶ 例えば、歴代総理大臣全員
■
明治以来、62人(95代)もいる
▶ 変数が増えすぎて面倒
■
番号が付けられる
▶ まとめて宣言、まとめて扱える
理化学研究所
平均点の計算:配列を使う
 List9-2(教科書p.208)
#include <stdio.h> 配列の型
int main(void);
配列の定義:個数を明示
int main(void)
{
int point[3];
配列の各要素
float heikin;
最大値とサイズは1ずれる
point[0]=65;
point[1]=90;
∵0から始まるため
point[2]=75;
heikin=(point[0]+point[1]+point[2])/3.0;
printf("鳩山%d点\n菅%d点\n野田%d点",point[0],point[1],point[2]);
理化学研究所
printf("平均は%.1f点\n",heikin);
return(0);
}
配列と箱詰め菓子
▶ 5個詰め合わせ
■
型が同じなら違う物が入っていても良い
和風菓からいも
和風菓からいも
okashi[3]
okashi[5]
理化学研究所
配列の要素
▶ 要素1つずつ:その型の変数と同じ
▶ int aa[3];
■
aa[0],aa[1],aa[2]はいずれもint型変数
理化学研究所
平均点の計算:変数の配列番号
 List9-3(教科書p.213)
#include <stdio.h>
int main(void);
int main(void)
{
int point[3], sum, ii;
float heikin;
point[0]=65;
point[1]=90;
point[2]=75;
sum=0;
for(ii=0;ii<3;ii++) {
sum=sum+point[ii];
}
heikin=sum/3.0;
printf("鳩山%d点\n菅%d点\n野田%d点
",point[0],point[1],point[2]);
printf("平均は%.1f点\n",heikin);
return(0);
}
理化学研究所
合計を求めるforループ
ここではsum=0
 Forループの中身を読む
1回ごとにpoint[ii]が足される
sum=0;
for(ii=0;ii<3;ii++) {
sum=sum+point[ii];
}
終わったときは、sum=Sii point[ii]
理化学研究所
平均点の計算:もっと多要素へ
マクロ定義:文字列の置き換え
 List9-4(教科書p.218)
#include <stdio.h>
#define MAX_SOURI 5
int main(void);
変数のキャスト
sum=0;
for(ii=0;ii<MAX_SOURI;ii++) {
sum=sum+point[ii];
}
heikin=(float)sum/(float)MAX_SOURI;
int main(void)
{
int point[MAX_SOURI];
int sum, ii;
float heikin;
point[0]=65;
point[1]=90;
point[2]=75;
point[3]=45;
point[4]=82;
printf("伊藤博文%d点\n",point[0]);
printf(“黒田清隆%d点\n",point[1]);
printf("山縣有朋%d点\n",point[2]);
printf("松方正義%d点\n",point[3]);
printf("伊藤博文%d点\n",point[4]);
printf("平均は%.1f点\n",heikin);
return(0);
}
理化学研究所
変数のキャスト
▶ キャストcast
■
英語では…「配役」
 投げるとか鋳造するとか呪うとか他の意味もある
 英語の本当の意味は、それらを包括する概念らしい
■
C言語では
 別の型の変数として扱わせる
 ()の中に役名の型を書き、直前に付ける
 例: (int)aa,
(double)ii, (float)xxとか
理化学研究所
マクロ定義とプリプロセッサ
▶ プリプロセッサー
▶ 先頭が「#」の行
■
■
コンパイルする直前に何かやらせる
#include <ファイル名>
 ファイル名の中身を一時的にコピーしてから
■
#define 第1文字列 第2文字列
 第1文字列を第2文字列で置き換える
 第1文字列は全て大文字にすることが多い
▶ 例:#define PI 3.14159265
理化学研究所
平均点の計算:もっと多要素へ
 List9-4(教科書p.218)
#include <stdio.h>
#define MAX_SOURI 5
int main(void);
sum=0;
for(ii=0;ii<MAX_SOURI;ii++) {
sum=sum+point[ii];
}
heikin=(float)sum/(float)MAX_SOURI;
int main(void)
{
int point[MAX_SOURI];
int sum, ii;
float heikin;
point[0]=65;
point[1]=90;
point[2]=75;
point[3]=45;
point[4]=82;
printf("伊藤博文%d点\n",point[0]);
printf("黒田清隆%d点\n",point[1]);
printf("山縣有朋%d点\n",point[2]);
printf("松方正義%d点\n",point[3]);
printf("伊藤博文%d点\n",point[4]);
printf("平均は%.1f点\n",heikin);
return(0);
}
理化学研究所
2次元配列、3次元配列
▶ 軽羹まんじゅう詰め合わせ
明石家
20個入り
karukan[5][4]
明石家
24個入り
karukan[2][4][3]
理化学研究所
2次元マップ
▶ 2次元にいる“敵”の数を表示する
void show_gmap(int
gmap[GSIZE][GSIZE],
int isize)
/* 全宇宙マップを表示する
2012/10/19 Handa
*/
{
int ii,jj;
printf(" :");
for(ii=0;ii<isize;ii++) {
printf("%3d ",ii);
}
printf("\n");
for(jj=0;jj<isize;jj++) {
printf("%3d:",jj);
for(ii=0;ii<isize;ii++) {
printf("%3d ",gmap[ii][jj]);
}
printf("\n");
}
return;
}
理化学研究所
2次元配列、3次元配列
▶ 「配列の配列」と考えても良い
明石家
karukan[5][4]
軽羹4個入り5本セット
明石家
理化学研究所
karukan[2][4][3]
軽羹3個入り4本2段セット
初期値の代入
▶ 基本は普通の変数と同じ
■
全体を{}でくくり、要素順に「,」で区切って並べる
 List9-4b
#include <stdio.h>
#define MAX_SOURI 5
int main(void);
for(ii=0;ii<MAX_SOURI;ii++) {
sum=sum+point[ii];
}
heikin=(float)sum/(float)MAX_SOURI;
初期化
int main(void)
{
int point[MAX_SOURI]
={65,90,75,45,82};
int sum=0, ii;
float heikin;
printf("伊藤博文%d点\n",point[0]);
printf(“黒田清隆%d点\n",point[1]);
printf("山縣有朋%d点\n",point[2]);
printf("松方正義%d点\n",point[3]);
printf("伊藤博文%d点\n",point[4]);
printf("平均は%.1f点\n",heikin);
return(0);
}
理化学研究所
文字コード
▶ ビットパターンを文字に1対1対応させる
■
英数字:1バイト(256種類)で足りる
 現状では、英数字はほとんどがASCIIコード
 昔使っていたコードの例:EBCDICコード
■
■
足りない場合:2バイト以上で1文字にする
仮名と常用漢字は2バイトで足りる
 現在、4種類並立:JIS、shift-JIS、EUC、UniCode
■
別の計算機やOSと情報交換する時には必要
理化学研究所
文字コード
▶ C言語では基本は1バイト文字
■
多バイト文字は拡張仕様
▶ 2バイト文字=仮名や漢字
■
printfで表示する以外は使わないのが無難
理化学研究所
文字の定数と変数
▶ 文字=1バイト整数
■
空白も1文字
charは文字型とも1バイト整数とも呼ぶ
▶ 文字の“定数”
■
例 'A', 'z', '@', '/', ' '
 変数名と識別するためにシングルクォート「'」で括る。
▶ 文字の変数
■
■
1バイト長の整数として書く
例 char aa; char moji; char my_initial;
理化学研究所
プログラムで確かめる
▶ 文字定数があるプログラム
■
ワンポイント:printf中の%c

コードに対応する文字を出力する
#include <stdio.h>
int main(void)
{ char aa;
aa='x';
printf("moji=%c=%d\n",aa,aa);
return 0;
}
理化学研究所
文字列
▶ 文字列=1バイト整数の1次元配列
▶ 文字の“定数”
■
例 "Handa", "My name is", "OK!\n"
 変数名と識別するためにダブルクォートで括る。
▶ 文字の変数
■
■
1バイト長の整数の1次元配列として書く
例 char aa[5]; char moji[8]; char my_initial[256];
理化学研究所
文字列の長さ
▶ 文字列は長さがまちまち→どうやって扱う?
▶ 「ここで終わり」を決める。 C言語だとNULL
 別のやり方の例:長さを別に覚えておく
■
文字列はNULLで1バイト余分に必要
理化学研究所
プログラムで確かめる
▶ 文字の配列を文字列として書く
#include <stdio.h>
int main(void);
int main(void)
{
char aa[13];
aa[0]='H';
aa[1]='e';
aa[2]='l';
aa[3]='l';
aa[4]='o';
aa[5]=' ';
aa[6]='w';
aa[7]='o';
aa[8]='r';
aa[9]='l';
aa[10]='d';
aa[11]='.';
aa[12]=NULL;
printf("%s\n",aa);
return 0;
}
理化学研究所
文字列の代入
▶ 1次元配列の代入と同じ
■
要素単位で1文字ずつ代入する
 forループで代入しても良いが…
■
専用の関数が既に用意されている
 strcpy(aa,bb);
 使用する時には、まず
#include <string.h>
理化学研究所
文字列の代入
▶ 文字列定数の初期値代入
■
■
配列の場合と同じ。この場合だけ=で代入可能
例 char myname[6]="handa";
 サイズは、null文字用に1バイト余分に用意する!
理化学研究所
プログラムで確かめる
▶ 1文字ずつ出力させる
#include <stdio.h>
#include <string.h>
int main(void);
int main(void)
{ int ii;
6文字目, bb[5]には何が?
char aa[6]="handa";
char bb[6];
strcpy(bb,aa);
for(ii=0;ii<6;ii++) {
printf("%c,%d\n",bb[ii],bb[ii]);
}
return(0);
}
理化学研究所
文字列の出力(表示)
▶ コードが表す文字として表示
▶ printf文での書式 %s
■
注意:%cはnullがなくてもよいが
%sはnullで終わっていないとまずい!
■
例 printf("moji=%s\n", moji);
■
理化学研究所
文字列の配列
▶ 「文字の2次元配列」を使えば良い
NULL文字分も忘れなく!
 List9-6(教科書p.222)
#include <stdio.h>
#define MAX_SOURI 5
int main(void);
int main(void)
{
int point[MAX_SOURI]
={65,90,75,45,82};
char name[MAX_SOURI][10]
={"Ito", "Kuroda",
"Yamagata", "Matsukata",
"Ito"};
int sum=0, ii;
float heikin;
for(ii=0;ii<MAX_SOURI;ii++) {
sum=sum+point[ii];
}
heikin=(float)sum/(float)MAX_SOURI;
for(ii=0;ii<MAX_SOURI;ii++) {
printf("%sは%d点\n", name[ii], point[ii]);
理化学研究所
}
return(0);
}