"错误:赋值给表达式,数组类型错误"当我指定一个结构字段(C)

时间:2016-05-14 10:02:24

标签: c arrays string struct initialization

我是初学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};

它有效。 我究竟做错了什么?

3 个答案:

答案 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位作为示例。