在“char *”类型中分配“char[100]”时,错误消息“不兼容类型”[复制]

时间:2022-11-11 16:11:21

This question already has an answer here:

这个问题已经有了答案:

The compiler gives me an error, "incompatible types when assigning to type ‘char[100]’ from type ‘char *’" when I try to execute the following line:

当我试图执行以下一行时,编译器会给我一个错误,“不兼容的类型”,当我试图执行以下一行时,“char *”类型的类型为char[100]。

records[i].address = records[i+1].address;

records is an array of struct rec with the following definition:

记录是struct rec的数组,其定义如下:

struct rec{
    char address[100];
}

Why is it giving me this error? The left and right side is the same type.

为什么它会给我这个错误?左边和右边是相同的类型。

4 个解决方案

#1


2  

char[100] is not the same type as char *. One is an array of 100 character variables, the other is a variable that contains the address of a character variable.

char[100]与char *不相同。一个是100个字符变量的数组,另一个是包含字符变量地址的变量。

You can "assign" a char[100] to a char * only because a "bare" array evaluates to the address of its first element - an address can't hold anything - it's not a variable, it's where a variable is.

您可以将一个char[100]“赋值”给一个char *,因为“bare”数组计算的是它的第一个元素的地址——一个地址不能保存任何东西——它不是一个变量,而是一个变量。

Thus,

因此,

char array[ 100 ];
char *ptr = array;

works, while

工作,而

char array[ 100 ];
char *ptr;
array=ptr;

does not. The first case is saying ptr now points to the first element of array. The second is "the address of array should be assigned the value of ptr, which is literally nonsense.

没有。第一个例子是,ptr现在指向数组的第一个元素。第二个是“数组的地址应该被分配到ptr的值,这简直是胡说。

#2


1  

You can't assign to arrays, and if you think about it, that doesn't make sense, to copy the contents of the array, assuming it's a string you need strcpy(), for example

你不能分配给数组,如果你考虑它,那就没有意义,复制数组的内容,假设它是字符串,你需要strcpy(),例如。

strcpy(records[i].address, records[i+1].address);

#3


0  

Previous answers have mentioned the difference between char a[] and char * a. I want to make it more cleanly.

之前的答案已经提到了char a[]和char * a之间的区别,我想让它更干净一些。

In char a[], a just denotes an array address, not a variable, which means it cannot be assigned. Actually, a will be replaced by the final address when it was compiled to executable. you can't assign a value to a value.

在char a[]中,a只是表示一个数组地址,而不是一个变量,这意味着它不能被分配。实际上,当它被编译成可执行文件时,将被最终的地址所取代。你不能给一个值赋值。

For example,

例如,

foo.c:

foo.c:

char *myvar = "hello";

int 
main() {
    return myvar[0];
}

run

运行

gcc foo.c -o foo ; objdump -S foo

You'll get:

你会得到:

mov    0x2003ef(%rip),%rax      # put value of `myvar` into %rax

movzbl (%rax),%eax              # put *myvar into %eax

After you replaced char *myvar = "hello" with char myvar[] = "hello", you'll just get one line:

当您用char myvar[] = "hello"替换char *myvar = "hello"之后,您将得到一行:

movzbl 0x2003e7(%rip),%eax    # put address of array `myvar` into %eax

#4


0  

First, I will assume that this question is about C++, since it's tagged C++. The C tag is problematic because C is a different language with similar but not exactly identical rules. And for programming the devil is in the details.

首先,我假设这个问题是关于c++的,因为它被标记为c++。C标签是有问题的,因为C是一种不同的语言,有相似但不完全相同的规则。而对于编程来说,魔鬼就是细节。

Now, given

现在,鉴于

int const n = ....;

struct rec{
    char address[100];
};

rec records[n];

you can't do

你不能做

records[i].address=records[i+1].address;

because a raw array isn't assignable. There's no good reason for it, AFAIK. But probably a main driver was that in early C one focused on being able to define functions that could work with any length array, and Brian Kernighan ridiculed Pascal (with array assignment) for its inability to express such generally useful functions.

因为原始数组是不可赋值的。这是没有理由的,AFAIK。但可能一个主要的驱动因素是,在早期的C语言中,一个重点是能够定义可以使用任何长度数组的函数,Brian Kernighan嘲笑Pascal(带有数组赋值),因为它不能表达这些通常有用的函数。

On the other hand, you can do

另一方面,你也可以。

records[i]=records[i+1];

because class instances are assignable by default.

因为类实例在默认情况下是可赋值的。

As a kind of opposite case (or similar case, depending on what features one focuses on), when a function returns a class instance by value, then its assignment operator lets you assign to the whole instance (because member functions can be called on rvalues), but the rvalue-ness of the function call expression prevents you from assigning to a basic type member. Both these rules, the one about array member and the one about rvalue, can seem pretty arbitrary to a beginner. And they are. ;-)

作为一种相反的情况(或类似的情况下,这取决于特性一个关注),当一个函数返回一个类实例的值,那么它的赋值运算符允许您指定整个实例(因为成员函数可以被称为右值),但函数调用表达式的rvalue-ness阻止你分配基本类型成员。这两个规则,一个关于数组成员和一个关于rvalue的规则,对于初学者来说都是很随意的。和他们。:-)

Anyway, what you should do is use a std::string instead of a raw array of char, like this:

无论如何,您应该做的是使用std::string而不是原始的char数组,像这样:

struct rec{
    std::string address;
};

Then you can assign just the address member, or the whole struct, as you wish.

然后,您可以按照您的意愿指定地址成员或整个结构。

#1


2  

char[100] is not the same type as char *. One is an array of 100 character variables, the other is a variable that contains the address of a character variable.

char[100]与char *不相同。一个是100个字符变量的数组,另一个是包含字符变量地址的变量。

You can "assign" a char[100] to a char * only because a "bare" array evaluates to the address of its first element - an address can't hold anything - it's not a variable, it's where a variable is.

您可以将一个char[100]“赋值”给一个char *,因为“bare”数组计算的是它的第一个元素的地址——一个地址不能保存任何东西——它不是一个变量,而是一个变量。

Thus,

因此,

char array[ 100 ];
char *ptr = array;

works, while

工作,而

char array[ 100 ];
char *ptr;
array=ptr;

does not. The first case is saying ptr now points to the first element of array. The second is "the address of array should be assigned the value of ptr, which is literally nonsense.

没有。第一个例子是,ptr现在指向数组的第一个元素。第二个是“数组的地址应该被分配到ptr的值,这简直是胡说。

#2


1  

You can't assign to arrays, and if you think about it, that doesn't make sense, to copy the contents of the array, assuming it's a string you need strcpy(), for example

你不能分配给数组,如果你考虑它,那就没有意义,复制数组的内容,假设它是字符串,你需要strcpy(),例如。

strcpy(records[i].address, records[i+1].address);

#3


0  

Previous answers have mentioned the difference between char a[] and char * a. I want to make it more cleanly.

之前的答案已经提到了char a[]和char * a之间的区别,我想让它更干净一些。

In char a[], a just denotes an array address, not a variable, which means it cannot be assigned. Actually, a will be replaced by the final address when it was compiled to executable. you can't assign a value to a value.

在char a[]中,a只是表示一个数组地址,而不是一个变量,这意味着它不能被分配。实际上,当它被编译成可执行文件时,将被最终的地址所取代。你不能给一个值赋值。

For example,

例如,

foo.c:

foo.c:

char *myvar = "hello";

int 
main() {
    return myvar[0];
}

run

运行

gcc foo.c -o foo ; objdump -S foo

You'll get:

你会得到:

mov    0x2003ef(%rip),%rax      # put value of `myvar` into %rax

movzbl (%rax),%eax              # put *myvar into %eax

After you replaced char *myvar = "hello" with char myvar[] = "hello", you'll just get one line:

当您用char myvar[] = "hello"替换char *myvar = "hello"之后,您将得到一行:

movzbl 0x2003e7(%rip),%eax    # put address of array `myvar` into %eax

#4


0  

First, I will assume that this question is about C++, since it's tagged C++. The C tag is problematic because C is a different language with similar but not exactly identical rules. And for programming the devil is in the details.

首先,我假设这个问题是关于c++的,因为它被标记为c++。C标签是有问题的,因为C是一种不同的语言,有相似但不完全相同的规则。而对于编程来说,魔鬼就是细节。

Now, given

现在,鉴于

int const n = ....;

struct rec{
    char address[100];
};

rec records[n];

you can't do

你不能做

records[i].address=records[i+1].address;

because a raw array isn't assignable. There's no good reason for it, AFAIK. But probably a main driver was that in early C one focused on being able to define functions that could work with any length array, and Brian Kernighan ridiculed Pascal (with array assignment) for its inability to express such generally useful functions.

因为原始数组是不可赋值的。这是没有理由的,AFAIK。但可能一个主要的驱动因素是,在早期的C语言中,一个重点是能够定义可以使用任何长度数组的函数,Brian Kernighan嘲笑Pascal(带有数组赋值),因为它不能表达这些通常有用的函数。

On the other hand, you can do

另一方面,你也可以。

records[i]=records[i+1];

because class instances are assignable by default.

因为类实例在默认情况下是可赋值的。

As a kind of opposite case (or similar case, depending on what features one focuses on), when a function returns a class instance by value, then its assignment operator lets you assign to the whole instance (because member functions can be called on rvalues), but the rvalue-ness of the function call expression prevents you from assigning to a basic type member. Both these rules, the one about array member and the one about rvalue, can seem pretty arbitrary to a beginner. And they are. ;-)

作为一种相反的情况(或类似的情况下,这取决于特性一个关注),当一个函数返回一个类实例的值,那么它的赋值运算符允许您指定整个实例(因为成员函数可以被称为右值),但函数调用表达式的rvalue-ness阻止你分配基本类型成员。这两个规则,一个关于数组成员和一个关于rvalue的规则,对于初学者来说都是很随意的。和他们。:-)

Anyway, what you should do is use a std::string instead of a raw array of char, like this:

无论如何,您应该做的是使用std::string而不是原始的char数组,像这样:

struct rec{
    std::string address;
};

Then you can assign just the address member, or the whole struct, as you wish.

然后,您可以按照您的意愿指定地址成员或整个结构。