差异初始化和归零的C / C数组++? [英] Difference in initializing and zeroing an array in c/c++?

查看:143
本文介绍了差异初始化和归零的C / C数组++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C(或者C ++),有什么之间的区别

In c (or maybe c++) , what's the difference between


char myarr[16]={0x00};



and


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

...

编辑:我问这个是因为在VC ++ 2005的结果是一样的..


编辑更多:

edit: I ask this because in vc++ 2005 the result is the same..
edit more : and

char myarr[16]={0x00,}; 




或许可以得到更多的COM prehensive答案,也不含糊如下一些答案指这种code,即。
刚刚闭幕的大括号前加上逗号。另外,结果是VC ++ 2005是一样的。

?
maybe can get more comprehensive answer and not ambiguous as some answers below refer to this kind of code,ie. put comma just before closing curly braces. Also the result is the same in vc++ 2005.

推荐答案

最重要的区别在于,第一个缺省在特定元素的方式初始化数组:指针将获得的空指针值的,这并不需要为0x00(如在所有位零),布尔将<青霉>假的。如果元素类型是不是一个类类型的所谓的 POD 的(普通的旧数据类型),那么你只能做第一个,因为第二个只适用于最简单的情况(在这里你没有的虚函数的,用户定义的构造函数等)。与此相反,使用memset的第二种方式设置该阵列的所有位零的所有元素。这并不总是你想要的。如果你的数组比如三分球,他们不会必然设置为空指针。

The important difference is that the first default initializes the array in an element-specific manner: Pointers will receive a null pointer value, which doesn't need to be 0x00 (as in all-bits-zero), booleans will be false. If the element type is a class type that's not a so-called POD (plain old data-type), then you can only do the first one, because the second one only works for the simplest cases (where you don't have virtual functions, user defined constructors and so on). In contrast, the second way using the memset sets all elements of the array to all-bits-zero. That is not always that what you want. If your array has pointers for example, they won't be set to null-pointers necessarily.

第一将默认初始化数组的元素,除了第一个,这被设置为0明确。如果阵列是本地和栈上(即,不是一个静态),编译器内部经常做了memset的清除阵列出来。如果数组是非本地或静态,第一版本可以是<青霉>有效的多的。编译器可以把已经初始化,在编译的时候,到生成汇编code,使得它不需要运行code在所有。此外,该阵列可以被自动zero'd出部分进行布局(也为指针,如果他们有一个所有位归零重新presentation)计划以快速的方式启动时(即页面级明智的)。

The first will default initialize the elements of the array, except for the first one, which is set to 0 explicitly. If the array is local and on the stack (that is, not a static), the compiler internally often does a memset to clear the array out. If the array is non-local or static, the first version can be considerably more efficient. The compiler can put the initializers already, at compile time, into the generated assembler code, making it require no runtime code at all. Alternatively, the array can be laid out on a section that is automatically zero'd out (also for pointers, if they have a all-bits-zero representation) when the program starts in a fast manner (i.e page-wise).

第二个做了memset的明确整个数组。优化编译器通常将取代memset的用于内嵌机code,它只是循环使用标签和分支机构较小的区域。

The second does a memset explicitly over the whole array. Optimizing compilers will usually replace a memset for smaller regions with inline machine code that just loops using labels and branches.

<子>
下面是第一种情况下产生的assembler- code。我的海湾合作​​委员会的东西不多了优化,所以我们到了一个memset的实际通话(堆栈顶部的16个字节总是分配,即使我们没有得到当地人$ n是一个注册号):

Here is assembler-code generated for the first case. My gcc stuff isn't much optimized, so we got a real call to memset (16 bytes at the stack-top are always allocated, even if we got no locals. $n is a register number):

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 ++标准的底层细节。第一种情况上面将默认初始化剩余的元素。

The gory details from the C++ Standard. The first case above will default-initialize remaining elements.

8.5

要零初始化存储方式:


      
  • 如果T是一个标量类型中,存储被设定为0(零)的值的转换至T

  •   
  • 如果T是一个非工会类类型,存储针对每个非静态数据成员和每个基级子对象是零初始化;

  •   
  • 如果T是一个联合类型,它的第一个数据成员的存储是零初始化;

  •   
  • 如果T是一个数组类型,每个元素的存储是零初始化;

  •   
  • 如果T是引用类型,不执行初始化。

  •   

要默认初始化类型T的对象是指:

To default-initialize an object of type T means:


      
  • 如果T是一个非POD类类型,T的默认构造函数被调用

  •   
  • 如果T是数组类型,每个元素都是默认初始化;

  •   
  • ,否则,该对象的存储是零初始化

  •   

8.5.1

如果有在列表更少初始化以外还有在聚集成员
  那么没有初始化每个成员应的默认初始化的(8.5)。

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数组++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆