フローチャート 3
フローチャート2 |
・ここで、C言語のプログラムを例にとり型宣言及び構造体について説明します。
<変数の型宣言>
今までMTTLやWTTLなどの変数を数字として定義済であることを前提として説明してきました。C言語の型宣言はプログラムの先頭で以下のように行います。
(フローチャートで型宣言は必要ありません。)
今までMTTLやWTTLなどの変数を数字として定義済であることを前提として説明してきました。C言語の型宣言はプログラムの先頭で以下のように行います。
(フローチャートで型宣言は必要ありません。)
変数の宣言 | 説明 |
---|---|
int MTTL; | 変数MTTLは整数データ(int)であることを宣言 |
int WTTL; | 変数WTTLは整数データ(int)であることを宣言 |
char NAME[32]; | 変数NAMEは32桁の文字(char)データであることを宣言 |
<文字列の代入>
いままで扱ってきた変数は主に整数タイプでした。
変数Xの内容を変数Yに代入するのに、フローではY=Xと記述してきました。これは実際のC言語でもY=X;と記述するので、便利な表現でした。
例題でもそろそろ文字列を取り上げますので、文字列変数Aを他の文字列変数Bにコピーするケースが出てきます。C言語の場合、標準で用意されている文字列コピー関数を使います。
(C言語の文法上の命令ではなく、関数を使用しなければいけないのです)
いままで扱ってきた変数は主に整数タイプでした。
変数Xの内容を変数Yに代入するのに、フローではY=Xと記述してきました。これは実際のC言語でもY=X;と記述するので、便利な表現でした。
例題でもそろそろ文字列を取り上げますので、文字列変数Aを他の文字列変数Bにコピーするケースが出てきます。C言語の場合、標準で用意されている文字列コピー関数を使います。
(C言語の文法上の命令ではなく、関数を使用しなければいけないのです)
・変数a,bの型宣言 | |
char a[16]; | 最大16文字までの文字列宣言 |
char b[16]; | 最大16文字までの文字列宣言 |
・C言語の文字列コピー | |
strcpy(a,"string copy"); | 文字列aに「string copy」という文字列をコピー |
strcpy(b,a); | 文字列bに文字列aをコピー |
文字列とは連続した文字の先頭番地を指し、文字の終わりはNULL文字(1バイトの数値0)
という約束になっています。
という約束になっています。
下図は16バイトの文字列aのイメージです。NULLがでてくるまでが有効な文字列です。
文字は1字1字の文字を扱うより文字列として扱うことが多く、上例の場合も文字列をコピーするstrcpyという標準関数を使用しています。
16バイト文字変数aを文字列として処理する(strcpy関数を使用)ためには最後にNULL文字が必要となるので、有効文字は15文字以内ということになります。
16バイト文字変数aを文字列として処理する(strcpy関数を使用)ためには最後にNULL文字が必要となるので、有効文字は15文字以内ということになります。
文字列としてではなく16バイトのデータ(文字、数値等)をコピーする場合はmemcpyという標準関数が用意されていてそれを使用します。
(最後NULLでなくても良いし、途中のNULLもコピー対象です。)
(最後NULLでなくても良いし、途中のNULLもコピー対象です。)
・C言語のデータコピー | |
memcpy(b,a,16); | 文字データbに文字データaを16バイトコピー |
<構造体>
例題6では生徒の性別はSEIテーブル、得点はTENテーブルに設定されていました。つまりある生徒の情報が別々のテーブルに保存され、生徒NOによって関連付けされていました。
これでは生徒に関する情報が増えると管理が複雑になりそうです。
生徒ごとに生徒に関連する情報が結合されていたら参照するときも、コピーする時も便利に使えそうです。
例題6では生徒の性別はSEIテーブル、得点はTENテーブルに設定されていました。つまりある生徒の情報が別々のテーブルに保存され、生徒NOによって関連付けされていました。
これでは生徒に関する情報が増えると管理が複雑になりそうです。
生徒ごとに生徒に関連する情報が結合されていたら参照するときも、コピーする時も便利に使えそうです。
下図はある生徒の座席NO(数値タイプ)、名前(文字タイプ)、得点(数値タイプ)の3つの情報を結合した生徒情報という名前の構造体のイメージです。
構造体は複数データの結合ですので構造体としての型をもち、タグ名といいます。struct SEITOはSEITOというタグ名(構造体)宣言です。構造体に含まれるデータをメンバと言い、データ型と名前を宣言します。 SEITO型の構造体メンバはsno(整数)、name(32文字)、ten(整数)です。左の例はaida(相田)という生徒情報の構造体です。 メンバは構造体名.メンバ名で表現できます。 |
例.aida.ten=87;(相田の得点に87を代入しました。)
構造体を使って配列を定義することもできます。左の例はタグ名SEITO構造体を使ったclass構造体配列宣言です。 配列サイズは26(0から25)です。 メンバは構造体名[添え字].メンバ名で表現できます。 |
例.class[3].ten=56;(class構造体配列の添字=3の得点に56を代入。)
strcpy(class[3].name, aida.name);(相田の名前をCLASS[3]の名前にコピー。)
<構造体のコピー>
構造体のコピーには2種類考えられます。構造体のメンバをコピーする場合はそのメンバの型に合わせてそれぞれをコピーします。
構造体のコピーには2種類考えられます。構造体のメンバをコピーする場合はそのメンバの型に合わせてそれぞれをコピーします。
例.class[3].ten=aida.ten;(相田の得点をCLASS[3](上条)の得点に代入。)
strcpy(class[3].name, aida.name);(相田の名前をCLASS[3]の名前にコピー。)
・構造体全体をまとめてコピーするにはどうしたらよいでしょうか?
まとまったデータのコピーは全てmemcpyです。Memcpyにはバイトサイズ指定が必要です。SEITOタグのサイズはint:4BYTEとすると、4+32+4=40バイト(実際にはもうチョッと面倒な算出方法になりますが、アトで)。実際にはsizeof(struct SEITO)、またはsizaof(aida)と書くと正しいサイズが求まります。)
まとまったデータのコピーは全てmemcpyです。Memcpyにはバイトサイズ指定が必要です。SEITOタグのサイズはint:4BYTEとすると、4+32+4=40バイト(実際にはもうチョッと面倒な算出方法になりますが、アトで)。実際にはsizeof(struct SEITO)、またはsizaof(aida)と書くと正しいサイズが求まります。)
例.memcpy(&class[3], &aida, 40);(相田構造体をCLASS[3]構造体にコピー。)
memcpy(&class[3], &aida, sizeof(aida));(上と同様。)
memcpy(&class[3], &class[5], 40);(CLASS[5]構造体をCLASS[3]にコピー。)
memcpy(&class[3], &class[5], sizeof(struct SEITO));(上と同様。)
※例では&(アンパサント)記号がついています。ポインタを意味しますがC言語の勉強のときに
説明しますので、現時点では気にしなくて結構です。
説明しますので、現時点では気にしなくて結構です。
・コピーが1つの処理でできることが判ったところで、実際のフロー上の表記ですが、以下のようにしましょう。
文字列のコピーaaa <- bbb
class[5].name <- class[3].name
構造体等まとまったデータのコピーclass[5] <- aida
class[5] <- class[3]
それでは例題6と同様の問題を構造体を使って解きます。
以下フローチャートの演習問題です。
14.下図のような生徒情報を持つ、構造体配列(SUT[26])と
構造体(SUM)があります。
構造体メンバは名前(NAME 10文字)文字タイプ
性(SEI 0:女、1:男)整数タイプ
数学点数(SUU 0~100)整数タイプ
英語点数(ENG 0~100)整数タイプ
合計点数(TTL 0~100)整数タイプ
AVEは実数タイプの配列です。
個人の英語と数学の合計をTTLメンバに算出し、
個人の英語と数学の平均をAVE配列[当該INDEX]に算出し、
全員のENGとSUUとTTL合計をSUM構造体に算出しなさい。
SUM.NAMEは"合計"をセットします。(SUM.SEIは0のまま)
15.演習14のデータを使って最高得点を取得した女性の名前を
WNAME(32文字の変数)に代入しなさい。
16.演習14の配列の添字17と添字18の生徒が同一名で並びが間違っていました。
順番を入替なさい。
フローチャート2 |