将字符串字面值的第一个字符赋值给字符数组将赋值整个字符串字面值

Assigning the first character of a string literal to a char array assigns entire string literal

本文关键字:赋值 字符 字面值 字符串 数组 第一个      更新时间:2023-10-16

我不确定下面的代码是如何工作的:

int p = 0;
char* arr = new char[20];
*((int*)&arr[p]) = *((unsigned int*)"ABCD");

以下是我的观察:

arr[p]                   returns a char
&arr[p]                  gets the address of the char (char*)
(int*)&arr[p]            casts the char* to int*
*((int*)&arr[p])         dereferences the int* to int
"ABCD"                   is a char*
(unsigned int*)"ABCD"    casts the char* to unsigned int*
*(unsigned int*)"ABCD"   dereferences the unsigned int* to unsigned int
然后将"ABCD"中的第一个字符"A"(将其解释为无符号整型)复制到arr中的第一个元素(将其解释为整型)。然而,经过检查,arr中的第一个元素不仅是'A',而且第二个,第三个和第四个元素分别是'B', 'C'和'D'。

我的问题是,如果我们只将"ABCD"中的第一个字符"A"复制到arr中的第一个元素,那么其他字符"B","C"answers"D"如何也被复制?

谢谢

你的观察是完全正确的,但是你似乎误解了右边的解引用和赋值的意思。

您没有复制(并转换)一个charunsigned int,但您有效地将sizeof(unsigned int)字节从一个地址复制到另一个地址。

这是一个原因,为什么c风格的强制转换是如此危险(1):你不是将一个char转换为一个unsigned int并分配它,你是将指针转换为一个char到指针unsigned int,然后解引用它。因此,当对右侧解引用时,编译器只假设从给定地址开始的四个字节(sizeof(unsigned int))包含一个unsigned int,并且只从unsigned int转换为int

你显然想要做的是:

*((int*)&arr[p]) = unsigned int("ABCD"[0]);

但是,请记住,正如M.M指出的那样,左边无论如何都是UB。

你写:

然后将"ABCD"中的第一个字符'A'(将其解释为无符号整型)复制到arr中的第一个元素(将其解释为整型)。

这个假设是错误的。

由于强制类型转换,*((int*)&arr[p]) = *((unsigned int*)"ABCD");复制了大小为4的unsigned int,因此也复制了B、C和D。

我希望你知道在现实生活中你不会写这样的代码。