@marumenさん
なるほどですね、アドバイスも詳しくて分かりやすいです!
つまりこんな感じでしょうか?以下、@marumenさんのアドバイスをもとに調べて分かった点について書いてみました。間違った箇所等あれば是非教えてください。
♢♢♢
プログラムにおける作成した関数までの部分
は
#include <stdio.h>
struct Animal {
int age;
double weight;
};
void set_animal_params(struct Animal *animal, int age, double weight) {
// (*animal).age は animal->age 、(*animal).weight は animal->weight と同じ
animal->age = age;
animal->weight = weight;
printf("set_animal print %d %f\n", animal->age, animal->weight);
}
void set_fail_animal_params(struct Animal animal, int age, double weight) {
animal.age = age;
animal.weight = weight;
printf("set_fail_animal print %d %f\n", animal.age, animal.weight);
}
void get_animal_params(struct Animal animal) {
printf("get_animal print %d %f\n", animal.age, animal.weight);
}
であるとして、
❶
set_animal_paramsは上記の1に該当し、メンバに値を設定するので引数がポインタ型
→set_animal_params関数
について。main関数にて&animal
という形でアドレス渡しをしているので、構造体Animalのメンバage,weightそれぞれに値を設定しても、正常にコンパイルされる。故に、main関数が以下のような時、エラーなく1と12.3を表示出来る。
int main(void) {
struct Animal animal;
set_animal_params(&animal, 1, 12.3);
return 0;
}
❷
get_animal_paramsは上記の2に該当し、メンバの値を読みだすので引数はポインタ型でなくていい
→get_animal_params関数
について。ここでは、最初にset_animal_params関数で 構造体Animalのメンバage,weightそれぞれに値を設定する
事で、get_animal_params関数も含めて正常にコンパイルされている。set_animal_params関数なしに(構造体へのアドレス渡しをせずに)、メンバの値を読み出すだけで構造体へのアドレス渡しをしていないget_animal_params関数は使用しない(そうしなければ、プログラムはコンパイルエラーつきで実行される)。main関数が以下のような時に、エラーなく1と12.3を表示出来る。
int main(void) {
struct Animal animal;
set_animal_params(&animal, 1, 12.3);
get_animal_params(animal);
return 0;
}
❸
set_fail_animal_paramsは関数内では値を設定できますが、設定した値をmain関数の変数animalには反映させることができません。
→set_fail_animal_params関数
は、get_animal_params関数と同じく、set_animal_params関数による構造体へのアドレス渡しなしには正常に実行出来ない。
また、これもget_animal_params関数と同じく、以下のようにset_fail_animal_paramsとset_animal_paramsを入れ替えてもコンパイルエラーとなる。
//コンパイルエラーになる
int main(void) {
struct Animal animal;
set_fail_animal_params(animal, 2, 45.6);
set_animal_params(&animal, 1, 12.3);
return 0;
}
気づいた点:アドレス渡しは、先に、必ず行う必要があるらしい。