gpt4 book ai didi

c++ - 在 C/C++ 中初始化和归零数组的区别?

转载 作者:IT老高 更新时间:2023-10-28 22:16:33 34 4
gpt4 key购买 nike

在 c (或者可能是 c++) 中,有什么区别

char myarr[16]={0x00};


char myarr[16];memset(myarr, '\0', sizeof(myarr));

??

编辑:我问这个是因为在 vc++ 2005 中结果是一样的..
编辑更多:和

char myarr[16]={0x00,}; 
?
也许可以得到更全面的答案,而不是模棱两可,因为下面的一些答案是指这种代码,即。将逗号放在大括号之前。结果在 vc++ 2005 中也是一样的。

最佳答案

重要的区别是第一个默认值以特定于元素的方式初始化数组:指针将接收一个 空指针值,它不需要是 0x00(如在所有位中) -zero), bool 值将是 false。如果元素类型不是所谓的POD(普通旧数据类型)的类类型,那么你只能做第一个,因为第二个只适用于最简单的情况(你没有虚拟函数、用户定义的构造函数等等)。相比之下,使用 memset 的第二种方法将数组的所有元素设置为所有位为零。这并不总是你想要的。例如,如果您的数组具有指针,则它们不一定会设置为空指针。

第一个将默认初始化数组的元素,但第一个除外,它显式设置为 0。如果数组是本地的并且在堆栈上(也就是说,不是静态的),编译器内部通常会执行一个 memset 来清除数组。如果数组是非本地的或静态的,第一个版本可能效率更高。编译器可以在编译时将初始化程序放入生成的汇编代码中,使其根本不需要运行时代码。或者,当程序以快速方式(即分页方式)启动时,可以将数组布置在自动归零的部分上(也适用于指针,如果它们具有全位零表示)。

第二个在整个数组上显式地执行 memset。优化编译器通常会将较小区域的 memset 替换为仅使用标签和分支循环的内联机器代码。

<子>这是为第一种情况生成的汇编代码。我的 gcc 的东西没有得到太多优化,所以我们真正调用了 memset(堆栈顶部的 16 个字节总是被分配,即使我们没有本地人。$n 是一个寄存器号):

void f(void) {
int a[16] = { 42 };
}

sub $29, $29, 88 ; create stack-frame, 88 bytes
stw $31, $29, 84 ; save return address
add $4, $29, 16 ; 1st argument is destination, the array.
add $5, $0, 0 ; 2nd argument is value to fill
add $6, $0, 64 ; 3rd argument is size to fill: 4byte * 16
jal memset ; call memset
add $2, $0, 42 ; set first element, a[0], to 42
stw $2, $29, 16 ;
ldw $31, $29, 84 ; restore return address
add $29, $29, 88 ; destroy stack-frame
jr $31 ; return to caller

来自 C++ 标准的血腥细节。上面的第一种情况将默认初始化剩余的元素。

8.5:

To zero-initialize storage for an object of type T means:

  • if T is a scalar type, the storage is set to the value of 0 (zero) converted to T;
  • if T is a non-union class type, the storage for each nonstatic data member and each base-class subobject is zero-initialized;
  • if T is a union type, the storage for its first data member is zero-initialized;
  • if T is an array type, the storage for each element is zero-initialized;
  • if T is a reference type, no initialization is performed.

To default-initialize an object of type T means:

  • if T is a non-POD class type, the default constructor for T is called
  • if T is an array type, each element is default-initialized;
  • otherwise, the storage for the object is zero-initialized.

8.5.1:

If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be default-initialized (8.5).

关于c++ - 在 C/C++ 中初始化和归零数组的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/453432/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com