C语言 “错误:分配给具有数组类型错误的表达式”当我分配结构字段 (C)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37225244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:24:59  来源:igfitidea点击:

"error: assignment to expression with array type error" when I assign a struct field (C)

carraysstringstructinitialization

提问by Chief096

I'm a beginner C programmer, yesterday I learned the use of C structs and the possible application of these ones about the resolution of specific problems. However when I was experimenting with my C IDE (Codeblocks 16.01) in order to learn this aspect of C programming, I've encountered a strange issue. The code is the following:

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

During the compilation, the compiler (GCC 4.9.3-1 under Windows) reported me an error that says

在编译过程中,编译器(Windows下的GCC 4.9.3-1)向我报告了一个错误,说

"error: assignment to expression with array type error"

“错误:赋值给具有数组类型错误的表达式”

on instruction

根据指示

s1.name="Paolo" 
s1.surname="Rossi" 

while if I do

如果我这样做

data s1 = {"Paolo", "Rossi", 19};

it works. What am I doing wrong?

有用。我究竟做错了什么?

回答by Sourav Ghosh

You are facing issue in

您正面临以下问题

 s1.name="Paolo";

because, in the LHS, you're using an arraytype, which is not assignable.

因为,在 LHS 中,您使用的是不可分配数组类型。

To elaborate, from C11, chapter §6.5.16

详细说明,从C11第 6.5.16 章开始

assignment operator shall have a modifiable lvalue as its left operand.

赋值运算符应有一个可修改的左值作为其左操作数。

and, regarding the modifiable lvalue, from chapter §6.3.2.1

并且,关于可修改的 lvalue,来自第 §6.3.2.1 章

A modifiable lvalue is an lvalue that does not have array type, [...]

可修改的左值是没有数组类型的左值,[...]

You need to use strcpy()to copy intothe array.

您需要使用strcpy()复制到阵列中。

That said, data s1 = {"Paolo", "Rossi", 19};works fine, because this is not a direct assignmentinvolving assignment operator. There we're using a brace-enclosed initializer listto provide the initial values of the object. That follows the law of initialization, as mentioned in chapter §6.7.9

也就是说,data s1 = {"Paolo", "Rossi", 19};工作正常,因为这不是涉及赋值运算符的直接赋值。在那里,我们使用大括号括起来的初始化列表来提供object的初始值。这遵循初始化定律,如第 §6.7.9 章所述

Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.[....]

每个花括号括起来的初始化列表都有一个关联的当前对象。当不存在指定时,当前对象的子对象根据当前对象的类型按顺序初始化:数组元素按递增下标顺序,结构成员按声明顺序,以及联合的第一个命名成员。[... .]

回答by teknopaul

typedef struct{
     char name[30];
     char surname[30];
     int age;
} data;

defines that datashould be a block of memory that fits 60 chars plus 4 for the int (see note)

定义data应该是一个适合 60 个字符加 4 个用于 int 的内存块(见注释)

[----------------------------,------------------------------,----]
 ^ this is name              ^ this is surname              ^ this is age

This allocates the memory on the stack.

这会在堆栈上分配内存。

data s1;

Assignments just copies numbers, sometimes pointers.

赋值只是复制数字,有时是指针。

This fails

这失败了

s1.name = "Paulo";

because the compiler knows that s1.nameis the start of a struct 64 bytes long, and "Paulo"is a char[] 6 bytes long (6 because of the trailing \0 in C strings)
Thus, trying to assign a pointer to a string into a string.

因为编译器知道这s1.name是一个 64 字节长的 struct 的开始,并且"Paulo"是一个 char[] 6 字节长(6 因为在 C 字符串中尾随 \0)
因此,尝试将指向字符串的指针分配到字符串中。

To copy "Paulo" intothe struct at the point nameand "Rossi" intothe struct at point surname.

以“保罗”复制该结构在点name和“罗西”点的结构surname

memcpy(s1.name,    "Paulo", 6);
memcpy(s1.surname, "Rossi", 6);
s1.age = 1;

You end up with

你最终得到

[Paulo0----------------------,Rossi0-------------------------,0001]

strcpydoes the same thing but it knows about \0termination so does not need the length hardcoded.

strcpy做同样的事情,但它知道\0终止,所以不需要硬编码的长度。

Alternatively you can define a struct which points tochar arrays of any length.

或者,您可以定义一个指向任何长度的 char 数组的结构。

typedef struct {
  char *name;
  char *surname;
  int age;
} data;

This will create

这将创建

[----,----,----]

This will now work because you are filling the struct with pointers.

现在这将起作用,因为您正在用指针填充结构。

s1.name = "Paulo";
s1.surname = "Rossi";
s1.age = 1;

Something like this

像这样的东西

[---4,--10,---1]

Where 4 and 10 are pointers.

其中 4 和 10 是指针。

Note: the ints and pointers can be different sizes, the sizes 4 above are 32bit as an example.

注意:int 和指针可以有不同的大小,上面的大小 4 以 32bit 为例。

回答by teknopaul

Please check this example here: Accessing Structure Members

请在此处查看此示例:访问结构成员

There is explained that the right way to do it is like this:

有解释说正确的做法是这样的:

strcpy(s1.name , "Egzona");
printf( "Name : %s\n", s1.name);