我是初学C程序员,昨天我学会了C结构的使用以及这些结构可能应用于特定问题的解决方案。但是当我尝试使用我的C IDE(Codeblocks 16.01)来学习C编程的这个方面时,我遇到了一个奇怪的问题。代码如下:
#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)向我报告了一个错误
&#34;错误:赋值给表达式,数组类型错误&#34;
指令
s1.name="Paolo"
s1.surname="Rossi"
如果我这样做
data s1 = {"Paolo", "Rossi", 19};
它有效。 我究竟做错了什么?
答案 0 :(得分:35)
您正面临
中的问题 s1.name="Paolo";
因为在LHS中,您使用的是数组类型,它不是可分配的。
详细说明,来自C11
,章节§6.5.16
赋值运算符应具有可修改的左值作为其左操作数。
和关于可修改的左值,来自章节§6.3.2.1
可修改的左值是一个左值 没有数组类型,[...]
您需要使用strcpy()
复制到数组中。
尽管如此,data s1 = {"Paolo", "Rossi", 19};
工作正常,因为这不是涉及赋值运算符的直接赋值。我们使用大括号括起初始化列表来提供对象的初始值。这遵循初始化定律,如章节§6.7.9
每个大括号括起的初始化列表都有一个关联的当前对象。什么时候没有 如果存在名称,则按照顺序初始化当前对象的子对象 到当前对象的类型:数组元素增加下标顺序,结构 声明顺序的成员,以及工会的第一个指定成员。[....]
答案 1 :(得分:11)
请在此处查看此示例:Accessing Structure Members
有人解释说正确的做法是这样的:
strcpy(s1.name , "Egzona");
printf( "Name : %s\n", s1.name);
答案 2 :(得分:8)
typedef struct{
char name[30];
char surname[30];
int age;
} data;
定义data
应该是一个适合60个字符的内存块加上4个用于int *
[----------------------------,------------------------------,----]
^ this is name ^ this is surname ^ this is age
这会在堆栈上分配内存。
data s1;
作业只是复制数字,有时是指针。
这失败
s1.name = "Paulo";
因为编译器知道s1.name
是64字节长的结构的开头,而"Paulo"
是一个char [] 6字节长(6因为C字符串中的尾随\ 0)<登记/>
因此,尝试将字符串指针分配给字符串。
复制&#34; Paulo&#34; 进入结点name
和&#34; Rossi&#34; 进入点surname
的结构。
memcpy(s1.name, "Paulo", 6);
memcpy(s1.surname, "Rossi", 6);
s1.age = 1;
你最终得到了
[Paulo0----------------------,Rossi0-------------------------,0001]
strcpy
执行相同的操作,但它知道\0
终止,因此不需要硬编码的长度。
或者,您可以定义指向任意长度的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。整数和指针可以是不同的大小,上面的大小4是32位作为示例。