天使と悪魔選手権

プログラムは以下です。
#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を結び付けている?ここもいまいちですが!?
 
 以上のコラボレーションをうまくご説明がしていただけるお方がおられましたら、
 ご教授のほどをよろしくお願いいたします。

質問者からの補足コメント

  • kei6663様レスで回答くださいまして誠にありがとうございます。 
     今からご回答の意味をよく理解したいと存じます。
    [i]がint型と、は私があくまでも予想の回答ですので外れている可能性が大です。
    気になさらないでくださいませ^^

      補足日時:2015/11/15 19:48
  • qq5z2tx9k様ご回答くださいまして誠にありがとうございました。
    一通り読ませていただきました。
     何回でも読まないと理解できませんので、理解できるまで読もうと思います。
     解決には、しばらくお待ちくださいませ

      補足日時:2015/11/15 22:45
  • siffon9様ご貴重な時間をご回答くださいまして誠にありがとうございました。
     さて!以下のご回答をもとにふと気づいたことがございます。
     4. gakusei[i]は、gakusei[0]~gakusei[2]のいずれか・・~
     int i,heikin;とfor (i = 0; i < GAKUSEI_NUM; i++)の" i "は別物でしたでしょうか
     私は同じものばかりと思っていたところですが!違わないと説明が変になるみたいと少
     し感じました、間違っていましたらすみません。
      よろしくお願いいたします。

      補足日時:2015/11/16 20:41
  • 皆様たくさんのご回答をくださいましてありがとうございます。
    一つ一つ詳しく調べながら読ませていただいております。
     私のレベルだと即理解するには少し時間がかかりそうですが、わかりやすいご回答と存じます。
     早く解決するようになるべく”ほかのことはさておき”、重点的に読ませていただいております。
     お待ち下さいませ^^

      補足日時:2015/11/16 22:15
  • 皆様時間がかかっておりまして申し訳ございません。
     さて、問題の点につきましては、まだ65%の理解度と存じます。
    明朝も4冊もある参考書を模索しております。
     納得がいくまで調べたいと存じます。

      補足日時:2015/11/20 05:54
  • 先ほど、構造体の配列宣言 を当問題が記載されています別の参考書で調べましたが、
    理解するのはなかなか難しです。
     この問題は”構造体の配列宣言”を勉強しないと解けないよう気がしています。

      補足日時:2015/11/21 07:32

A 回答 (6件)

> &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)正確には異なる可能性がありますが、今回の説明では問題ないと考えます。
    • good
    • 0
この回答へのお礼

素晴らしい図付きのご回答と長い間お付き合いくださいまして
 誠にありがとうございました。
  理解できたみたいと存じますが、本当に理解したのかは
 私のレベルだとまだわかりません。 今はそれしか言えません・・・
 
(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);
       を
 当てはめてみるとその通りの流れでプログラムは上から下へと
流れて行ってるように見受けれれます、

お礼日時:2015/11/21 15:01

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になります。
    • good
    • 0
この回答へのお礼

ご多忙中の折と存じますが
 回答くださいまして誠にありがとうございます。
 これごときで!かなり苦戦しております。

お礼日時:2015/11/18 05:10

「文法上」はおかしくないよ>#4. 意味的におかしいだけ.

    • good
    • 0

&gakusei[i].shimei は文法上おかしいですが、&gakusei[i].shimei[0] なら問題ありません。


(世の中には &gakusei[i].shimei を &gakusei[i].shimei[0] と解釈するコンパイラもありますが...)
この場合、 gakusei[i].shimei と &gakusei[i].shimei[0] は同じ意味で、同じアドレスを示します。
    • good
    • 0

> 以上の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文から抜けます)
    • good
    • 0
この回答へのお礼

詳しい御解説等ご回答くださいまして誠にありがとうございました。
 解決にあたり、色んな基礎的な項目に目を通しました。 
&gakusei[i].shimeiの代替の流れはわかりました^^
 scanfの入力項目である、  
氏名:国語の得点:数学の得点:×3組めで”i が 0 から 2 まで。i < 3 なので i が 3 になったところで、 3 < 3はなりたたなくなり、for文から抜けます)”
  なるほどですね^^
さて
 やっと次の項目に移れます、今後ともよろしくお願いいたします。

お礼日時:2015/11/21 14:51

自分は超がつくほどプログラミング初心者なので、参考にならないかもしれませんが





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型というのはよくわかりません
    • good
    • 1
この回答へのお礼

早々ご回答いただいていまして、お礼が遅れましたことをお詫びも仕上げます。
 さて
  最後のご回答から
scanfを使うことによりchar型のshimei[80]、int型のkokugo,sugaku,eigoがGAKUSEI_NUM個作れたことになります。”個別”がキーワード
 
 なるほどですね^^素人なりにわかります。
 今回は
 ”構造体の配列宣言”もまだいまいち理解していないことに後で気づき
  調べましたが結構簡単ではないみたいですが・・・
 なので、今回の私の質問は”構造体の配列宣言”を理解することで
 質問の本質がわかってくると存じます。
 今わかりましたことは
scanf("%s", &gakusei[i].shimei);の
 &gakusei[i].shimei);は、学生はループ上は3名までの限定で
以後、3名分の国語 数学 英語 の点数を入力すると
 ループから抜ける・・・
 だろうと思います。

お礼日時:2015/11/21 07:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!