数组与字符串初始化为空的深入理解

正题

1. 一维数组初始化,可以只给一部分元素赋值,如下

int a[10] = {0,1,2,3,4};
这样只给前面的5个元素赋值,后5个元素为0。
将char p[8]; 看作是字符数组的话, charp[8]={0}; 表示第一个元素为0,后面的7个元素也为0;
所以 char p[8] = {}和charp[8]={0}一样; 8个元素都初始化为0
2.用字符串常量来使字符数组初始化
char p[10] = "china";
前5个元素为‘c’,‘h‘,‘i‘,‘n‘,‘a‘,
第6个元素为‘\0‘
后4个元素为空字符,即‘\0‘
所以用char p[8] = "";初始化,8个元素都是‘\0‘;
//‘0‘表示结束标志,代表ASCII码为0的字符
所以用 char p[8] = ""; 和 char p[8] = {0}; 都能够将8个元素初始化为0;
char p[8] = {0}; 当作字符数组看待,常规数组初始化;
char p[8] = "";  用字符串常量初始化

附注

#define ARRAYSIZE 2048
voidmain() {
chararrayA[ARRAYSIZE]={0};
chararrayB[ARRAYSIZE];
memset(array,0, ARRAYSIZE);
}

char arrayA[ARRAYSIZE] = {0};
编译是先arrayA[0]赋值为0, 再调用memset初始化其他的数组元素.

char arrayA[ARRAYSIZE] = {0};
效率很难比用memset高,因为综上分析,我觉得给一块内存赋值的效率很难超越memset。

memset

语法:

#include <cstring>void*memset(void*buffer,intch,size_tcount);

memset()拷贝chbuffer的前count字符中,并返回buffer。memset()对于以某一值初始化一段内存非常有用。例如,这个命令:

constintARRAY_LENGTH=300;
charthe_array[ARRAY_LENGTH];
// zero out the contents of the_array
memset(the_array,\0, ARRAY_LENGTH);

…是非常有效率的方法来设置the_array中的所有值为零。

下表比较了两种不同的方式来初始化字符数组:for循环和memeset()。随着初始化数据量的增加,memset()很清晰的做的更快:

耗时 for循环 memset
1000 0.016 0.017
10000 0.055 0.013
100000 0.443 0.029
1000000 4.337 0.291

几条不成熟的建议

1:非必要情况不对内存使用memset清零,尤其是大块内存。

2:如某结构体或内存块在使用前会逐一赋值,则不需要对其进行memset初始化。

3:字符串的初始化可以对其第一个字节赋值0。

使用strcpy拷贝的字符串不需要进行初始化。

使用strncpy拷贝的字符串,建议不要先进行memset全部清零,而是在strncpy后,根据字符串实际长度,对字符串后一个字节置零。

在做流程判断的时,尽量减少使用字符串比较,而采用整形或布尔量比较。

4:减少结构体转换和copy代码。对结构体尤其是包含长字符串的结构体复制时,建议慎用memcpy,而采取逐一赋值的方式。

5: 非必要不使用malloc和free,不但容易造成内存泄露,而且动态分配内存快时,系统的内存堆状况可能会影响分配效率(比如内存碎片很多时)。建议对一些动态分配的数组,采用定义一个足够大的数组方式.(这里有个问题:局部变量的最大尺寸是多少呢,也就是说进程栈空间是多少呢?这个应该是有限制的,但是每种操作系统或编译器的限制是多少呢,应该不能在栈空间里定义一个几十M或一个G大的数组吧?)

6:unix程序是基本上是以进程模式运行的,可以合理使用全局静态变量。减少分配内存的开销。在多线程程序里慎用全局变量




郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。