我不确定下面的代码是如何工作的:
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"one_answers"D"如何也被复制?
谢谢
你的观察是完全正确的,但是你似乎误解了右边的解引用和赋值的意思。
您没有复制(并转换)一个char
到unsigned 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。
我希望你知道在现实生活中你不会写这样的代码。