c++数组初始化与删除用法大全
Posted bitcarmanlee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++数组初始化与删除用法大全相关的知识,希望对你有一定的参考价值。
0.前言
大家公认的c++学习曲线比较陡峭,在我看来很重要一个原因就是c++语法比较灵活,要实现某个功能可能有好多种写法都能实现,所以很多时候就容易给大家带来困扰,搞不清楚为什么要这么写,或者这么写到底为啥,跟我平时写的为什么不一样。比如我们常用的数组,其初始化/删除就有非常多的方式,而且这些方式也比较混乱,没有特别的规律,很容易把人给直接绕晕圈了。下面我们来针对数组的初始化/删除方式做一个总结,如果有不对或者不全的地方,大家可以进行指正补充。
1.静态初始化
比较常见的初始化方式为静态初始化。下面我们来看实例
void static_init()
int a[5] = 1, 2, 3, 4, 5;
int b[3] = 1;
int c[5] = 1,;
const int n = 3;
int d[n] = 1, 2, 3;
for(int i=0; i<sizeof(a)/sizeof(a[0]); i++) cout<<a[i]<<" ";
cout<<endl;
for(int i=0; i<sizeof(b)/sizeof(b[0]); i++) cout<<b[i]<<" ";
cout<<endl;
for(int i=0; i<sizeof(c)/sizeof(c[0]); i++) cout<<c[i]<<" ";
cout<<endl;
for(int i=0; i<sizeof(d)/sizeof(d[0]); i++) cout<<d[i]<<" ";
cout<<endl;
1 2 3 4 5
1 0 0
1 0 0 0 0
1 2 3
上面的写法都是可以的。
数组a的初始化方法最为常见,直接用大括号初始化,大括号内的元素个数与数组声明时长度一致。
数组b大括号内的元素小于数组声明长度,不足的元素按0的默认值填充。
数组c的初始化方式与b类似。值得注意的是,在有些资料上会说c的方式有错误,但是经过本人实测,c的初始化方式是可以正常运行的,c++版本为11。
数组d初始化时长度为变量n,注意此时必须要求n为const类型,否则会报错。
以下方式均为错误的。
// int n = 3;
// int f[n] = 1, 2, 3; error: variable-sized object may not be initialized
// int f[5] = 1,,1; error: int [5](int)1, (<error-type>)<error-constant>, (<error-type>)<error-constant>
// int f[5] = 1, 2, 3, 4, 5, 6; error: excess elements in array initializer
2.字符串常量初始化字符数组
我们还经常用字符串常量初始化字符数组,这种用法特别常见。
void char_init()
char cs[8] = "abcedfg";
char c2[5] = "abc";
cout<<sizeof(cs)<<endl;
cout<<sizeof(c2)<<endl;
上面都是用一个字符串初始化字符数组,注意默认会在字符数组最后加上’\\0’。如果字符常量长度不够数组其他元素自动初始化为 ‘\\0’。
3.不指定长度初始化
void other_init()
int nums[] = 1, 2, 3;
cout<<sizeof(nums)/sizeof(nums[0])<<endl;
上面的代码最终会输出3。初始化的时候,没有专门指定数组长度,但是列表内的元素个数会决定数组长度。
4.动态初始化数组
void dynamic_init()
int *a = new int[3];
for(int i=0; i<3; i++) cout<<a[i]<<" ";
cout<<endl;
int *b = new int[3]();
for(int i=0; i<3; i++) cout<<b[i]<<" ";
cout<<endl;
memset(b, 1, sizeof(int)*3);
for(int i=0; i<3; i++) cout<<b[i]<<" ";
上面代码输出:
0 0 0
0 0 0
16843009 16843009 16843009
动态初始化数组,则利用到了new关键字。使用new时,如果在运行阶段需要数组,则创建它;如果不需要,则不创建。还可以在程序运行时选择数组的长度。这被称为动态联编。意味着数组是在程序运行时创建的。这种数组叫做动态数组。在运行时确定数组的长度。
new出来的数据,需要用一个指针接收,返回的则是第一个元素的地址。
另外注意的是,new int[3]与new int3的效果一致,最后得到的都是默认值为0长度为3的一个整型数组。
另外我们需要注意的是,用memset函数时,进行设置时候,是一个字节一个字节进行设置。上面的写法,是将数组b的每个字节都设置为1,即0x01010101,换算成对应的十进制则为16843009。
5.删除动态数组
void dynamic_v2()
int *p = new int[3];
p[0]=0, p[1]=1, p[2]=2;
for(int i=0; i<3; i++) cout<<p[i]<<" ";
cout<<endl;
*p=10, *(p+1)=11, *(p+2)=12;
for(int i=0; i<3; i++) cout<<p[i]<<" ";
cout<<endl;
*p=20, *(++p)=21, *(++p)=22;
p-=2; // 注意此时p已经指向了第三个元素,需要先减2回到起始位置
for(int i=0; i<3; i++) cout<<p[i]<<" ";
cout<<endl;
delete [] p;
for(int i=0; i<3; i++) cout<<p[i]<<" ";
0 1 2
10 11 12
20 21 22
20 21 22
使用new与delete时,我们需要注意以下事项:
1.delete不能释放不是new关键字分配的内存。
2.delete不能释放同一个内存两次。
3.如果是用new []为数组分配内存,则我们应该使用delete []释放。
4.对空指针进行delete是可以的,安全的。
上面代码需要注意的是:我们对p进行delete操作以后,似乎还能访问到原内存中的数据,这个就比较奇怪了,为什么会这样?
指针被delete以后,并没有被设置为NULL,此时delete只是把指针所指向的内存给释放掉,并没有把指针本身干掉,此时指针指向的是“垃圾”内存,这种指针成为悬挂指针(dangling pointer)。
所以一般我们delete完以后,可以将指针设置为NULL。
以上是关于c++数组初始化与删除用法大全的主要内容,如果未能解决你的问题,请参考以下文章