私は初心者のCプログラマーです。昨日、C構造体の使用と、特定の問題の解決に関するこれらの構造体の可能なアプリケーションを学びました。しかし、Cプログラミングのこの側面を学習するためにC IDE(コードブロック16.01)を試していたときに、奇妙な問題に遭遇しました。コードは次のとおりです。
#include <stdio.h>
#define N 30
typedef struct{
char name[N];
char surname[N];
int age;
} data;
int main() {
data s1;
s1.name="Paolo";
s1.surname = "Rossi";
s1.age = 19;
getchar();
return 0;
}
コンパイル中に、コンパイラ(WindowsのGCC 4.9.3-1)から次のエラーが報告されました。
「エラー:配列型エラーのある式への割り当て」
指導中
s1.name="Paolo"
s1.surname="Rossi"
している間
data s1 = {"Paolo", "Rossi", 19};
できます。私は何を間違えていますか?
あなたは問題に直面しています
s1.name="Paolo";
lHSでは、arrayタイプではなく、assignableを使用しているためです。
詳しく説明するには、C11
の6.5.16章から
代入演算子は、左オペランドとして変更可能な左辺値を持たなければなりません。
そして、変更可能な左辺値に関して、§6.3.2.1章から
変更可能な左辺値は、配列型を持たない左辺値です[...]
strcpy()
を使用して、配列をコピー先にする必要があります。
とは言っても、data s1 = {"Paolo", "Rossi", 19};
は正常に機能します。これは、代入演算子を伴う直接的な割り当てではないためです。そこで、brace-enclosed initializer listを使用して、objectの初期値を提供しています。これは、§6.7.9の章で述べた初期化の法則に従います。
各中括弧で囲まれた初期化リストには、現在のオブジェクトが関連付けられています。指定がない場合、現在のオブジェクトのサブオブジェクトは、現在のオブジェクトのタイプに応じた順序で初期化されます。添字の昇順の配列要素、宣言の順序の構造体メンバー、および共用体の最初の名前付きメンバー。[... 。]
ここでこの例を確認してください: Accessing Structure Members
それを行う正しい方法は次のようであると説明されています:
strcpy(s1.name , "Egzona");
printf( "Name : %s\n", s1.name);
typedef struct{
char name[30];
char surname[30];
int age;
} data;
data
は、60文字とint *に4を合わせたメモリブロックでなければならないことを定義します
[----------------------------,------------------------------,----]
^ this is name ^ this is surname ^ this is age
これにより、スタック上のメモリが割り当てられます。
data s1;
割り当ては単に数字、時にはポインターをコピーするだけです。
これは失敗します
s1.name = "Paulo";
コンパイラは、s1.name
が64バイト長の構造体の始まりであり、"Paulo"
が6バイト長のchar []であることを知っているため(C文字列の末尾\ 0のため6)
したがって、文字列へのポインタを文字列に割り当てようとしています。
"Paulo" intoname
の構造体と "Rossi" intosurname
の構造体をコピーします。
memcpy(s1.name, "Paulo", 6);
memcpy(s1.surname, "Rossi", 6);
s1.age = 1;
で終わる
[Paulo0----------------------,Rossi0-------------------------,0001]
strcpy
は同じことをしますが、\0
終端については知っているので、ハードコーディングされた長さは必要ありません。
または、任意の長さのpoints char配列である構造体を定義できます。
typedef struct {
char *name;
char *surname;
int age;
} data;
これは作成します
[----,----,----]
これは、構造体をポインターで埋めているため機能します。
s1.name = "Paulo";
s1.surname = "Rossi";
s1.age = 1;
このようなもの
[---4,--10,---1]
4と10はポインターです。
* N.B。 intとポインターは異なるサイズにすることができ、上記のサイズ4は例として32ビットです。