プログラムは以下です。
#include <stdio.h>
#include <string.h>
/* 学生の人数 */
#define GAKUSEI_NUM 3
/* 構造体の定義 */
struct TestKekka
{
char shimei[80];
int kokugo;
int sugaku;
int eigo;
};
int main(int argc, char* argv[])
{
int i,heikin;
/* 構造体の配列の宣言 */
struct TestKekka gakusei[GAKUSEI_NUM];
/* 学生のデータ入力する */
for (i = 0; i < GAKUSEI_NUM; i++)
{
printf("氏名:");
scanf("%s", &gakusei[i].shimei);
printf("国語の得点:");
scanf("%d", &gakusei[i].kokugo);
printf("数学の得点:");
scanf("%d", &gakusei[i].sugaku);
printf("英語の得点:");
scanf("%d", &gakusei[i].eigo);
printf("---------------\n");
}
------------------------------------------------------------------------------------------
プログラムは以上ですが、
/* 学生のデータ入力する */
for (i = 0; i < GAKUSEI_NUM; i++)
{
printf("氏名:");
scanf("%s", &gakusei[i].shimei);
------------------------------------------------------------------------------------------
以上のscanf("%s", &gakusei[i].shimei);の&gakusei[i].shimeiの部分がよくわからないのですが!?
&はアドレス
gakusei は 配列変数名
[i]はint型
.は構造体メンバー演算子でshimeiを結び付けている?ここもいまいちですが!?
以上のコラボレーションをうまくご説明がしていただけるお方がおられましたら、
ご教授のほどをよろしくお願いいたします。
No.3ベストアンサー
- 回答日時:
> &gakusei[i].shimeiの部分がよくわからないのですが!?
1. gakuseiは、タグ名TestKekka構造体の配列(要素数は、0~2の3個)
2. タグ名TestKekaは、shimei[80],kokugo,sugaku,eigoのメンバ変数で構成されている。
3. 構造体のメンバ shimeiは、char型変数の配列(要素数は、0~79の80個)
4. gakusei[i]は、gakusei[0]~gakusei[2]のいずれか
5. gakusei[i].shiemeiは、gausei[i]のメンバshimei[80]の先頭アドレス
以上は、メモリ上に下記の様に配置されています(※1)
変数i は0~2のいずれかなので、
gakusei[i].shiemeiは下記右側の矢印部分のいずれかになります。
(既に回答がついている様に、shimei[80]は配列なので
先頭アドレスは&が付かないgakusei[i].shimeiになります。)
――――――――― shimei[ 0](char型) ←ここがgakusei[0].shimeiの場所(アドレス)
↑ shimei[ 1](char型)
この範囲が ……
gakusei[0] shimei[79](char型)
│ kokugo(int型)
↓ sugaku(int型)
――――――――― eigo(int型)
――――――――― shimei[ 0](char型) ←ここがgakusei[1].shimeiの場所(アドレス)
↑ shimei[ 1](char型)
この範囲が ……
gakusei[1] shimei[79](char型)
│ kokugo(int型)
↓ sugaku(int型)
――――――――― eigo(int型)
――――――――― shimei[ 0](char型) ←ここがgakusei[2].shimeiの場所(アドレス)
↑ shimei[ 1](char型)
この範囲が ……
gakusei[2] shimei[79](char型)
│ kokugo(int型)
↓ sugaku(int型)
――――――――― eigo(int型)
(※1)正確には異なる可能性がありますが、今回の説明では問題ないと考えます。
素晴らしい図付きのご回答と長い間お付き合いくださいまして
誠にありがとうございました。
理解できたみたいと存じますが、本当に理解したのかは
私のレベルだとまだわかりません。 今はそれしか言えません・・・
(i = 0; i < GAKUSEI_NUM; i++)
と
printf("氏名:");
scanf("%s", &gakusei[i].shimei);
printf("国語の得点:");
scanf("%d", &gakusei[i].kokugo);
printf("数学の得点:");
scanf("%d", &gakusei[i].sugaku);
printf("英語の得点:");
scanf("%d", &gakusei[i].eigo);
を
当てはめてみるとその通りの流れでプログラムは上から下へと
流れて行ってるように見受けれれます、
No.6
- 回答日時:
No.3です。
> int i,heikin;とfor (i = 0; i < GAKUSEI_NUM; i++)の" i "は別物でしたでしょうか
> 私は同じものばかりと思っていたところですが!
いえ、同じものですよ。
int i,heikin; で変数の使用を宣言して、for(i = 0; i < GAKUSEI_NUM; i++){……}で実際に使用していますよね。
No.2さんが書かれている様に、for文の中で変数i は、0,1,2,3と増加して、i が3(=GAKUSEI_NUMで定義している値)になったところでfor文を抜けます。
ですから、for文の中で使用される変数i の値は、0~2になります。
No.4
- 回答日時:
&gakusei[i].shimei は文法上おかしいですが、&gakusei[i].shimei[0] なら問題ありません。
(世の中には &gakusei[i].shimei を &gakusei[i].shimei[0] と解釈するコンパイラもありますが...)
この場合、 gakusei[i].shimei と &gakusei[i].shimei[0] は同じ意味で、同じアドレスを示します。
No.2
- 回答日時:
> 以上のscanf("%s", &gakusei[i].shimei);の&gakusei[i].shimeiの部分がよくわからないのですが!?
まず、scanf関数の仕様上第2引数以降(第1引数も)は入力された値が格納されるべき変数のアドレスを指定する必要があります。
構造体TestKekkaのメンバーであるshimeiはchar型の配列でありC言語の文法上、配列の変数名だけ記述した場合、その変数の値が格納されているアドレスを意味します。
よってこの場合、&gakusei[i].shimeiは正しい記述ではありません。&を取ったgakusei[i].shimeiの記述で、構造体TestKekkaの型を持つ配列変数gakuseiの「i 番目」のshimeiのアドレスを示すことになります。他のメンバーである kokugo、sugaku、eigoは 配列でない int型であるため、アドレスを示したい場合には変数名の先頭に & を付けます。
[i]は、先に記述した通り「構造体TestKekkaの型を持つ配列変数gakuseiの「i 番目」」を示すものです。変数 i はint型ですね。 このプログラムの場合 GAKUSEI_NUM が 3 で定義されていることから、i は for文によって 0 から 3 までの値をとります。i が 3 になったところで、for文の中身({ ~ } まで)は実行されずに次の構文へ実行が移されます。(for文の中身が実行されるのは i が 0 から 2 まで。i < 3 なので i が 3 になったところで、 3 < 3はなりたたなくなり、for文から抜けます)
詳しい御解説等ご回答くださいまして誠にありがとうございました。
解決にあたり、色んな基礎的な項目に目を通しました。
&gakusei[i].shimeiの代替の流れはわかりました^^
scanfの入力項目である、
氏名:国語の得点:数学の得点:×3組めで”i が 0 から 2 まで。i < 3 なので i が 3 になったところで、 3 < 3はなりたたなくなり、for文から抜けます)”
なるほどですね^^
さて
やっと次の項目に移れます、今後ともよろしくお願いいたします。
No.1
- 回答日時:
自分は超がつくほどプログラミング初心者なので、参考にならないかもしれませんが
scanf関数の使い方やポインタの使いかたを見れば&の使い方がわかると思います。
&はアドレス演算子っていいます。変数が入ってるメモリのアドレスを表示する演算子です。
変数をaとおくと、aのアドレスは&aです。
構造体は配列を扱うこともできます。
struct a{
int b;
int c;
};
struct a a1;
とおくと
a1.bとa1.cという2つの変数が使えます。
たとえば、a1.b=1 ; a1.c=2;のように値を入れて使えます。
これを
struct a{
int b;
int c;
};
struct a a1[2];
とおくと
a1[0].b a1[0].c
a1[1].b a1[1].c
という4つの変数が使えます。
配列の大きさが多いほどたくさんの変数が作れます。
同じように、
a1[0].b=1;
a1[0].c=2;
a1[1].b=3;
a1[1].c=4;
のように使えます。
つまり
struct TestKekka
{
char shimei[80];
int kokugo;
int sugaku;
int eigo;
};
struct TestKekka gakusei[GAKUSEI_NUM];
for (i = 0; i < GAKUSEI_NUM; i++)
{
scanf("%s", &gakusei[i].shimei);
scanf("%d", &gakusei[i].kokugo);
scanf("%d", &gakusei[i].sugaku);
scanf("%d", &gakusei[i].eigo);
}
だとscanfを使うことによりchar型のshimei[80]、int型のkokugo,sugaku,eigoがGAKUSEI_NUM個作れたことになります。
[i]がint型というのはよくわかりません
早々ご回答いただいていまして、お礼が遅れましたことをお詫びも仕上げます。
さて
最後のご回答から
scanfを使うことによりchar型のshimei[80]、int型のkokugo,sugaku,eigoがGAKUSEI_NUM個作れたことになります。”個別”がキーワード
なるほどですね^^素人なりにわかります。
今回は
”構造体の配列宣言”もまだいまいち理解していないことに後で気づき
調べましたが結構簡単ではないみたいですが・・・
なので、今回の私の質問は”構造体の配列宣言”を理解することで
質問の本質がわかってくると存じます。
今わかりましたことは
scanf("%s", &gakusei[i].shimei);の
&gakusei[i].shimei);は、学生はループ上は3名までの限定で
以後、3名分の国語 数学 英語 の点数を入力すると
ループから抜ける・・・
だろうと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
構造体のextern方法
-
C#で配列が空かを判定するには?
-
MFC - ダイアログボックスのPic...
-
c言語
-
RAW画像高速表示について
-
フィボナッチ数列の求め方
-
C言語において、 配列要素をひ...
-
C言語の穴埋め問題です
-
vector配列の重複を無くすには?
-
MFCのCArrayを使った二次元配列
-
char gyou[1024];でcharの表現...
-
Cプログラムについて
-
C言語 数値の連続入力について
-
AfxBeginThread の引数について
-
define で 配列
-
C#でのフィボナッチ数列
-
C++DLLからC#へのコールバック...
-
int i, int i[1];
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
c言語
-
c言語プログラミング 等差数列...
-
define で 配列
-
構造体のextern方法
-
C#で構造体の配列を持った構造...
-
C言語において、 配列要素をひ...
-
MFC - ダイアログボックスのPic...
-
C言語の2次元配列 容量が大き...
-
2次元配列のマスを数える方法...
-
C言語 ファイルの指定された行...
-
Cのエラー
-
コンボボックスでデフォルト値...
-
C#で配列が空かを判定するには?
-
C#でのフィボナッチ数列
-
ポインタを使って構造体の配列...
-
C言語の課題が出たのですが自力...
-
MFCのCArrayを使った二次元配列
-
C言語の配列のコピーについて
おすすめ情報
kei6663様レスで回答くださいまして誠にありがとうございます。
今からご回答の意味をよく理解したいと存じます。
[i]がint型と、は私があくまでも予想の回答ですので外れている可能性が大です。
気になさらないでくださいませ^^
qq5z2tx9k様ご回答くださいまして誠にありがとうございました。
一通り読ませていただきました。
何回でも読まないと理解できませんので、理解できるまで読もうと思います。
解決には、しばらくお待ちくださいませ
siffon9様ご貴重な時間をご回答くださいまして誠にありがとうございました。
さて!以下のご回答をもとにふと気づいたことがございます。
4. gakusei[i]は、gakusei[0]~gakusei[2]のいずれか・・~
int i,heikin;とfor (i = 0; i < GAKUSEI_NUM; i++)の" i "は別物でしたでしょうか
私は同じものばかりと思っていたところですが!違わないと説明が変になるみたいと少
し感じました、間違っていましたらすみません。
よろしくお願いいたします。
皆様たくさんのご回答をくださいましてありがとうございます。
一つ一つ詳しく調べながら読ませていただいております。
私のレベルだと即理解するには少し時間がかかりそうですが、わかりやすいご回答と存じます。
早く解決するようになるべく”ほかのことはさておき”、重点的に読ませていただいております。
お待ち下さいませ^^
皆様時間がかかっておりまして申し訳ございません。
さて、問題の点につきましては、まだ65%の理解度と存じます。
明朝も4冊もある参考書を模索しております。
納得がいくまで調べたいと存じます。
先ほど、構造体の配列宣言 を当問題が記載されています別の参考書で調べましたが、
理解するのはなかなか難しです。
この問題は”構造体の配列宣言”を勉強しないと解けないよう気がしています。