初始化和赋值有什么不同?

3
1.char str[] = "hello"; //legal  

2.char str1[];
str1 = "hello"; // illegal

我理解“hello”返回字符串字面量池中的地址,不能直接分配给数组变量。在第一种情况下,“hello”字面量中的字符一个接一个地复制到数组中,末尾加上‘\0’。
这是因为赋值运算符“=”在此处被重载以支持此操作吗?
我还想知道其他有趣的情况,其中初始化与赋值不同。

5
实际上char str1[];也是不合法的。 - banarun
@banarun 是的,你说得对。我们需要声明数组的大小。 - 0decimal0
4个回答

4

不能认为这是重载(在C语言中并不存在),因为使用字符串字面值初始化字符数组是一种特殊情况。 字符串字面值的类型是const char[N],所以如果它类似于重载,你应该能够使用任何类型为const char[N]的表达式来初始化字符数组。 但是你不行!

const char arr[3];
const char arr1[] = arr; //compiler error. Cannot initialize array with another array.

语言标准简单地说明了字符数组可以用字符串字面量进行初始化。由于它们没有关于赋值的说明,因此一般规则适用,特别是数组不能被赋值。
至于其他情况下初始化与赋值不同的情况:在C++中,有引用和类,会有无数个例子。在C中,没有完整的类或引用,我能想到的唯一另一个例子就是const变量:
const int a = 4; //OK;
const int b; //Error;
b = 4; //Error;

另一个例子:使用大括号初始化数组。
int a[3] = {1,2,3}; //OK
int b[3];
b = {1,2,3}; //error

同结构体一样。

3
如果你想把它看作是运算符重载(尽管C语言没有使用这个术语),那当然可以这样做。
你是否也认为这是重载:
unsigned char x;
double y;

x = 2;
y = 1.243;

毕竟,它们分配完全不同类型的数据,但使用“相同的运算符”,对吗?

初始化或分配只是不同

另一个重要的区别是,您过去可以初始化结构,但是没有相应的“结构字面量”语法供以后分配使用。从C99开始,我们现在有复合字面量


你能给我其他基本数据类型初始化与赋值不同的实例吗? - Nithish Inpursuit Ofhappiness
@NithishInpursuitOfhappiness struct 是另一个类似的例子:struct x { int a; char c; } a = {1, '1'}; 是有效的,但之后你不能执行 a = {2, '1'}; - Grijesh Chauhan
@GrijeshChauhan 你看了我的回答吗?在C99中(其实并不是很新),你肯定可以这样做:a = ((struct x) { 2, 'a' }); - unwind
现在重新阅读,可以像这样分配数组int a[]= {1,2,3}然后在我的代码中使用a = (int[3]){3,2,1};在c99中吗? - Grijesh Chauhan

1
char str[] = "hello";

使用C语言中定义的语法糖进行数组初始化,因为字符串初始化非常常见。编译器会在程序中分配一些固定的内存并对其进行初始化。数组的名称(str)评估为该内存的地址,并且它不能被更改,因为没有变量保存该地址。
Grijesh Chauhan解释了更多细节。
其他情况取决于您的意思。扩展当前情况,可以轻松看出其他已初始化的数组具有相同的属性,例如。
int a[] = { 1, 2, 3, 4 };

感谢您的赞赏,但我已经删除了我的答案,因为我认为数组寻找其他初始化示例,在赋值中不是有效的。根据标题回答。 - Grijesh Chauhan

0

数组具有不可修改的地址。您需要一个指针作为可修改的lvalue。

通过分配(尝试)常量字符串文字,您正在获取其地址。不同的地址导致违法。

“hello”在内存中分配了一些空间并给出了一个地址。然后您取其地址来初始化数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接