「C言語/中級者向けの話題」の版間の差分

削除された内容 追加された内容
構造体配列のコードの実行結果の表示例を追加。
単元『C言語/構造体・共用体』に移動した構造体配列の話題を除去。
タグ: 置換
1 行
== 構造体と配列の組み合わせ ==
=== 構造体を配列化したもの ===
たとえば、学校での生徒の成績表のような、文字型と数値型が混ざるデータ構造を作りたい場合、つまり、異なる型を組み合わせたデータ構造をつくる場合には、構造体(または共用体)を要素とした配列をつくる必要がある。このような、配列と構造体を組み合わせたデータ構造は、ネット上では「構造体配列」または「構造体の配列」などと紹介されている。(構造体については、詳しくは『[[C言語/構造体・共用体]]』で。)
 
:※ かならずしも配列から構造体を呼び出さなくても良いが、実務上は、もし成績の構造体だけをつくっても、それを配列にしないと、実用的には不便である。なぜなら、配列でない個別の変数(構造体変数)に代入していく方式だと、たとえば成績表なら、クラスの人数ぶんだけ構造体変数を用意したりするハメになりかねない。たとえば1クラス当たり35人の学級なら、35個の構造体変数を用意するのは煩雑である。
:よって成績表をつくるためには、まず構造体の機能で1人ぶんの氏名と成績とのデータの結びつけを作り、それを配列で生徒数のぶんだけ複製するのである。
 
学校の成績表なら、まだクラスの生徒数がせいぜい数十名なので、構造体変数を数十個書くという方法でも、なんとか対応できる。だが、もし、大企業による提供サービスの登録者の会員名簿とかだと、会員数が数万名とかになるので、もはや構造体変数を1個ずつ書いていく方式は、不可能である。
 
 
Windowsの Visual C++ での構造体配列のコードの例を下記に示す。
 
(※ 他のコンパイラだとエラーになる場合もある。)
 
<syntaxhighlight lang="cpp">
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 「続行するには何かキーを押してください . . .」を表示するのに必要。
 
struct seisekihyou {
char seitomei[100];
int syusseki_bangou;
int kokugo_tensuu;
int sugaku_tensuu;
};
 
int main(void)
{
struct seisekihyou student[2]; // 構造体配列の宣言
 
strcpy_s( student[0].seitomei, 10 ,"山田");
student[0].kokugo_tensuu = 80;
student[0].sugaku_tensuu = 70;
 
strcpy_s(student[1].seitomei, 10 , "佐藤");
student[1].kokugo_tensuu = 60;
student[1].sugaku_tensuu = 90;
 
int i = 0;
 
for (i = 0; i<2; i = i + 1)
{
printf("名前: %s, 国語: %d点, 数学: %d点\n", student[i].seitomei, student[i].kokugo_tensuu, student[i].sugaku_tensuu);
}
 
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
 
return 0;
}
</syntaxhighlight>
 
:※ 上記のコードの動作確認として、 Visual Studio 2017 のCommunity 無料版でのC++で動作を確認ずみである。
 
 
;実行結果
名前: 山田, 国語: 80点, 数学: 70点
名前: 佐藤, 国語: 60点, 数学: 90点
 
 
いっぽう、gccコンパイラの場合、strcpy_s ではなく strcpy にしないと行けないので、上記のコードは使えないので、gccで動作させるには下記のようなコードになる。
 
<syntaxhighlight lang="cpp">
// gcc での構造体配列の例
 
#include <stdio.h>
#include <string.h>
 
struct seisekihyou {
char seitomei[100];
int syusseki_bangou;
int kokugo_tensuu;
int sugaku_tensuu;
};
 
int main(void)
{
struct seisekihyou student[2]; // 構造体配列の宣言
 
strcpy( student[0].seitomei ,"山田");
student[0].kokugo_tensuu = 80;
student[0].sugaku_tensuu = 70;
 
strcpy(student[1].seitomei, "佐藤");
student[1].kokugo_tensuu = 60;
student[1].sugaku_tensuu = 90;
 
int i = 0;
 
for (i = 0; i<2; i = i + 1)
{
printf("名前: %s, 国語: %d点, 数学: %d点\n", student[i].seitomei, student[i].kokugo_tensuu, student[i].sugaku_tensuu);
}
 
return 0;
}
</syntaxhighlight>
:※ 上記のコードの動作確認として、Fedora 28 (Linuxの一種)上での gcc で動作を確認ずみ。
 
=== 要素として配列を含む構造体 ===
また、上述の場合(構造体を配列化したもの)とは別の場合として、複数個の数値の集まり(これは配列で表現できる)に名前を命名したい場合(要素として配列を含む構造体をつくりたい場合)も多い。
 
 
どちらの場合にせよ、実務上は、おそらく配列と構造体との組み合わせでコードを書く必要にせまられる事も多いだろう。
 
構造体も共用体もつかわずに配列だけを使用した場合には、成績表のような異なる型がまざったデータの集まりを扱えない。
 
== 配列の文法についての制限 ==
=== 宣言時にしか、配列に一括で代入できない ===