前提・実現したいこと
構造体を用いて、氏名と身長・体重を順に表示したい。
発生している問題・エラーメッセージ
invalid initializer PHYSICAL *pdata[3] = &data[3];
該当のソースコード
C言語
1#include <stdio.h> 2#include <math.h> 3 4typedef struct physical { 5 char name[64]; 6 float height; 7 float weight; 8} PHYSICAL; 9 10int 11main(void) 12{ 13 int i; 14 15 PHYSICAL data[] = { 16 {"Yamada 0taro", 168.9, 61.8}, 17 {"Yamada 1taro", 163.6, 70.1}, 18 {"Yamada 2taro", 177.8, 58.7} 19 20 21 }; 22 PHYSICAL *pdata[3] = &data[3]; 23 24 25 for (i = 0; i < sizeof data / sizeof data[0]; i++) { 26 printf("%s %e %e\n", pdata[i]->name, pdata[i]->weight, pdata[i]->height); 27 } 28 return 0; 29}
試したこと
エラーメッセージの箇所をどのように変更すればよいかわかりません。
補足情報(FW/ツールのバージョンなど)
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
pdata
は大きさ3の配列なので、
C
1PHYSICAL *pdata[3] = {なにか, なにか, なにか};
のように初期化します。1-2個しか書かないときは残りには0
が入ります。
何を入れたいのか不明ですが、例えば、
C
1 PHYSICAL *pdata[3] = {&data[0],&data[1],&data[2]};
ただ、これだとわざわざpdata
を作る意味が無いですが。
投稿2019/12/21 14:17
総合スコア85882
0
もう回答は出揃っているようですし「pdata要らないよ」が正答な気がしますが
ソースコードを見る限り「ポインタの扱いが分からないまま雰囲気で書いた」感が強いのでポインタの扱いについて1つ。
C
1PHYSICAL *pdata[3];
と書いた場合これは「PHYSICALのポインタ型の要素を持つ長さ3の配列」を意味します。
つまり各要素はPHYSICAL*になります。
対して
C
1&data[3];
は「dataの4番目の要素のポインタ」の意味になります。元々dataは長さ3なのではみ出ていますし、
仮に配列dataの先頭要素のポインタを取得したい場合は単にdataもしくは&data[0]になります。
つまりもしpdataを使うのであれば
C
1PHYSICAL *pdata = data;
が正解ですが今回の場合全く必要がありません。
ちなみにこれはポインタを代入しているだけなので中身は複製されていません(同じものを見ている)
ポインタの概念は難解かもしれませんが、重要なので一度きっちり理解しておくと後々のために良いかと思います。
投稿2019/12/22 03:47
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
Cでは、「配列」はデータが密に並んだデータ構造です。data[N]とdata[N+1]は必ずお隣さん同士なので、data[N]の場所がわかればdata[N+1]の場所もわかる...つまりdata[0]の場所さえ知っていれば、任意のdata[N]は計算でわかるでしょ、だから配列を扱うときは先頭要素へのポインタだけ受け渡しすれば最低なんとかなるよね! と割り切ってしまったのがCの配列の扱いの原則です。(ただし、その割り切りの結果配列を関数に渡すとサイズの情報は失われますから、必要なら別途渡す必要はあります。)
つまり、単純にN個のデータを関数に渡してごにょごにょするための施策としては、PHYSICAL *pdata[3]
のようなものを設ける意味は全くありません。
ひとりずつのBMIから全員の平均BMIを求める関数と全員の身長と体重の測定値の標本平均と標準偏差の推定値を求める関数を定義し
というのが本来の目的であったなら、
C
1#include <stdio.h> 2 3typedef struct physical { 4 char name[64]; 5 float height; 6 float weight; 7} PHYSICAL; 8 9void printData(PHYSICAL dt[], size_t sz) {//本番ではBMI計算してどーたら、して下さい 10 for (int i = 0; i < sz; i++) { 11 printf("%s %e %e\n", dt[i].name, dt[i].weight, dt[i].height); 12 } 13} 14 15int main(void) { 16 PHYSICAL data[] = {{"Yamada 0taro", 168.9, 61.8}, 17 {"Yamada 1taro", 163.6, 70.1}, 18 {"Yamada 2taro", 177.8, 58.7}}; 19// 配列を単独で記述したら配列の先頭要素へのポインタと解釈される 20// 配列を引数に渡すと、ポインタと解釈されるので要素数の情報は別途渡さないといけない 21// 要は、これで配列の情報が全て関数に伝えられるということ 22 printData(data, sizeof data / sizeof data[0]); 23 return 0; 24}
このようなことがあなたがやるべきことじゃないでしょうか。
PHYSICAL *を導入しなきゃと考えてしまったところで道を誤ったと思います。まぁ、この段階でいろいろ歩き回ってみるのはいい勉強になるでしょうから、「誤った」といっても必ずしも悪いことじゃありませんね。
PHYSICAL *を導入したらどういうことが出来るかと言うと、例えば元の配列をいじらずに順番の変更が出来ます(ソートしたりとか)。こんなプログラムなら、PHYSICAL *が有効に使えるでしょう。
C
1#include <math.h> 2#include <stdio.h> 3 4typedef struct physical { 5 char name[64]; 6 float height; 7 float weight; 8} PHYSICAL; 9 10int main(void) { 11 int i; 12 13 PHYSICAL data[] = {{"Yamada 0taro", 168.9, 61.8}, 14 {"Yamada 1taro", 163.6, 70.1}, 15 {"Yamada 2taro", 177.8, 58.7} 16 17 }; 18 PHYSICAL *pdata[sizeof data / sizeof data[0]]; // sizeof演算子はコンパイル時に静的に値が決まっているのでVLA扱いにならない 19 for (i = 0; i < sizeof data / sizeof data[0]; i++) {//いわゆる初期化 20 pdata[i] = &data[i]; 21 } 22 //最初の状態を表示 23 for (i = 0; i < sizeof data / sizeof data[0]; i++) { 24 printf("%s %e %e\n", pdata[i]->name, pdata[i]->weight, pdata[i]->height); 25 } 26 printf("\n"); 27 //データを入れ替えてみる 28 PHYSICAL *tmp = pdata[1]; 29 pdata[1] = pdata[0]; 30 pdata[0] = tmp; 31 //入れ替えたものを表示 32 for (i = 0; i < sizeof data / sizeof data[0]; i++) { 33 printf("%s %e %e\n", pdata[i]->name, pdata[i]->weight, pdata[i]->height); 34 } 35 printf("\n"); 36 //元データは変更されていない 37 for (i = 0; i < sizeof data / sizeof data[0]; i++) { 38 printf("%s %e %e\n", data[i].name, data[i].weight, data[i].height); 39 } 40 printf("\n"); 41 42 return 0; 43}
投稿2019/12/22 01:22
総合スコア7703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
配列名がポインタになるので、関数にそれを渡せます。
C
1#include <stdio.h> 2#include <math.h> 3 4typedef struct physical { 5 char name[64]; 6 float height; 7 float weight; 8} PHYSICAL; 9 10void print(const PHYSICAL *pdata, int n) 11{ 12#if 1 // #if 0 にすると、#else のコードになります。 13 for (int i = 0; i < n; i++) 14 printf("%s %e %e\n", 15 pdata[i].name, pdata[i].weight, pdata[i].height); 16#else 17 for (int i = 0; i < n; i++, pdata++) 18 printf("%s %e %e\n", 19 pdata->name, pdata->weight, pdata->height); 20#endif 21} 22 23int main(void) 24{ 25 PHYSICAL data[] = { 26 {"Yamada 0taro", 168.9, 61.8}, 27 {"Yamada 1taro", 163.6, 70.1}, 28 {"Yamada 2taro", 177.8, 58.7}, 29 }; 30 print(data, sizeof data / sizeof data[0]); 31 return 0; 32}
投稿2019/12/21 17:04
総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
PHYSICAL *pdata[3] = &data[3];
この文が意味不明です
pdataはポインタの配列ですが、右辺の初期化式は配列になってません
投稿2019/12/21 14:23
編集2019/12/21 14:24総合スコア88038
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/21 14:49
2019/12/21 14:53
2019/12/21 14:55
2019/12/21 15:05
2019/12/21 15:23
2019/12/21 22:47
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/21 14:23
2019/12/21 14:26
2019/12/21 14:35
2019/12/21 14:56