質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

2521閲覧

構造体の配列メンバの初期化ができない

takadaibuoyancy

総合スコア17

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/08/09 05:26

ごちゃごちゃしてますがシンプルな質問なのでどうかお付き合いください。

コンパイルエラーの内容

構造体HANDの中に配列のメンバgcp[3][9]をつくり、mainの中で二つのHAND構造体cpuとyouのgcpに初期値を代入しようとしています。
が、下の写真のようにコンパイルエラーが出てしまいます。
イメージ説明

コード

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> typedef struct Hand{ char hand[9]; int num; char gcp[3][9]; }HAND; int main(){ HAND *cpu,*you; cpu->gcp=you->gcp={"rock","scissors","paper"};//←ここが問題の場所 time_t t; time(&t); //↓以下続くが無関係なので省略 //・・・ //・・・ //・・・ }

回答の程よろしくお願いいたします。m(__)m

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/08/09 05:34

しつもんはなんですか? "初期化できないのは何故か" ですか? "初期化するにはどうするか" ですか?
takadaibuoyancy

2020/08/09 06:31

すみません、説明不足でした。なぜできないのか、ですね。
guest

回答2

0

ベストアンサー

Cにおいて初期化という言葉は多少ブレがあるので気をつけて使った方がよいかと思います。
文法レベルでいう初期化は、変数を宣言と同時に値を与えるものです。
一方、プログラムのロジックとして初期化という場合は、その変数を使用するまでに適切な値を設定することをいいます。方法は、先の文法的な初期化でもいいですし、代入やメモリ直書きでもなんでもいいです。
質問でやろうとしていることは、代入によろうとしているので後者の初期化です。

さて。
構造体は代入が出来ますが、配列には(初期化は出来ても)代入は出来ません。Cでは、配列は単独で記述されると配列の先頭要素を指すポインタと解釈されてしまい、要素数は得られないため配列の代入は不可能です。

そして、

C

1typedef struct Hand{ 2 char hand[9]; 3 int num; 4 char gcp[3][9]; 5}HAND;

を見れば、gcpは配列ですから、これに代入することは出来ません。

HAND *cpu,*you;はポインタだから、そのポインタが指す場所を適切に指定しないままにその要素に値を設定しようとしていることもそれはそれでやってはいけないことですが、それは文法エラー(コンパイルエラー)にはなりません。(最近のお利口なコンパイラだとエラーにすることも出来るかも知れませんが)

投稿2020/08/09 06:06

thkana

総合スコア7639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takadaibuoyancy

2020/08/09 06:39

おっしゃる通りですね。配列の評価値が先頭のアドレスだったことを忘れていました。またthkanaさんとkazuma-sさんがおっしゃっていたようにその後mallocでポインタの指す領域を確保しました。ありがとうございます。
guest

0

HAND *cpu, *you; だと cpu も you もポインタですね。
ポインタはどこかにある HAND の実体(メモリ)を指さないと使えません。
malloc でメモリ領域を確保するとか、既に存在する HAND型の変数 hand の
アドレスを cpu = &hand; のように設定しないといけません。

宣言時に初期化しなかったものを後で初期化するには、
代入や memcpy や strcpy を使います。scanf の場合もあります。

C

1#include <stdio.h> // puts 2#include <stdlib.h> // malloc, free 3#include <string.h> // memcpy 4 5typedef struct Hand { 6 char hand[9]; 7 int num; 8 char gcp[3][9]; 9} HAND; 10 11int main(void) 12{ 13 static char gcp[3][9] = { "rock", "scissors", "paper" }; 14 HAND cpu, *you; // cpu は実体、you はポインタ 15 16 memcpy(cpu.gcp, gcp, sizeof gcp); 17 puts(cpu.gcp[0]); 18 19 you = malloc(sizeof(HAND)); 20 memcpy(you->gcp, gcp, sizeof gcp); 21 puts(you->gcp[1]); 22 free(you); 23}

追記
static char gcp[3][9] = { "rock", "scissors", "paper" }; を用意しなくても

memcpy(cpu.gcp, (char[3][9]){"rock","scissors","paper"}, sizeof cpu.gcp);

と書けるようです。

sizeof cpu.gcpsizeof(char[3][9]) でもかまいません。

投稿2020/08/09 05:41

編集2020/08/09 05:58
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問