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++数组初始化与删除用法大全相关推荐

  1. c的关于数组初始化 和 memset用法

    今天为了彻底搞定一个关于c中数组初始化和声明不同情况下,比如只声明一个数组char str[20];那么这str里面是什么内容呢?我用vc6++,debug下看到都是-56饿asc码,后来请教了一个华 ...

  2. 微信小程序——数组操作 (增加删除修改遍历)map、filter、forEach、find的用法、二维数组,排序,求和、指定长度数组赋值

    一.数组的操作 Array.push() ->在数组后面继续插入内容 Array.pop() ->拿走数组最后一个内容 Array-shift()->拿走数组的第一个内容 (unsh ...

  3. 【ADB 操作命令详解及用法大全(非常全)】

    ADB操作命令详解及用法大全 一.ADB是什么?   ADB,即 Android Debug Bridge 是一种允许模拟器或已连接的 Android 设备进行通信的命令行工具,它可为各种设备操作提供 ...

  4. C++Vector浅析,Vector用法大全

    vector基本概念 功能: vector数据结构和数组非常相似,也成为单端数组 vector与普通数组的区别: 不同之处在与数组是静态空间,而vector可以动态扩展 动态扩展: 并不是在原空间之后 ...

  5. C++——CString用法大全

    VC:CString用法大全 列表形式的如下: CString的构造函数 CString( ); 例:CString csStr; CString( const CString& string ...

  6. 史上最全面的 ADB命令 及用法 大全

    史上最全面的 ADB命令 及用法 大全 ADB Usage Complete / ADB 用法大全 https://mazhuang.org/awesome-adb/ ADB,即 Android De ...

  7. C# MessageBox 用法大全(转)

    C# MessageBox 用法大全 http://www.cnblogs.com/Tammie/archive/2011/08/05/2128623.html 我们在程序中经常会用到MessageB ...

  8. 神秘的数组初始化_I / O神秘化

    神秘的数组初始化 由于对高度可扩展的服务器设计的所有炒作以及对Node.js的狂热,我一直想重点研究IO设计模式,直到现在为止都没有足够的时间进行投资. 现在已经做了一些研究,我认为最好记下我遇到的东 ...

  9. 神秘的数组初始化_图像识别神秘化

    神秘的数组初始化 by gk_ 由gk_ 图像识别神秘化 (Image Recognition Demystified) Nothing in machine learning captivates ...

最新文章

  1. TP5的请求响应参数
  2. 确诊新冠小米员工的活动轨迹,这就是人间真实吗?
  3. android 清空canvas部分内容_Android自定义View实现圆形头像效果
  4. linux内核编译后 make: 警告:检测到时钟错误.,系统时钟 make: 警告:检测到时钟错误。您的创建可能是不完整的。...
  5. leetcode数组汇总_LeetCode刷题实战43:字符串相乘
  6. Android第三方开源FloatingActionButton(com.getbase.floatingactionbutton)【1】
  7. C/C++线程与多线程工作笔记0005---c/c++中的wchar_t类型
  8. zune自搭虚拟服务器离线升级,Zune 30g 购买/使用 个人经验贴,希望可以帮到有需要的烧友~...
  9. linux下安装微软雅黑字体库
  10. 认知升级是比其他一切技能都更为重要的思维模式转变
  11. NameError: name ‘weights‘ is not defined
  12. 良仓远行 · 硅谷遇上西雅图,同游招募
  13. iOS高性能Model转换框架----YYModel学习
  14. Aspose.Cells - 在任何平台上操作Excel电子表格
  15. 大数据在电力行业的应用案例100讲(二十三)-敏感性分析在园区能源互联网项目经济评价中的应用
  16. css游戏练习基础网址
  17. python翻译器怎么用_Python使用百度翻译开发平台实现英文翻译为中文功能示例
  18. python编程图_如何使用Python编程图形的X / Y图
  19. 阿里云数据库专家王颜培:我做MySQL云原生这些年
  20. gmail邮箱怎么收不到邮件

热门文章

  1. 动物运动会(C# 面向对象编程)(全)
  2. 自定义AlertDialog.Builder对话框
  3. 服务器的本质是什么?
  4. java条形图_java使用jfreechart绘制条形统计图
  5. fedora27 搜狗输入法配置
  6. c语言 指针的偏移计算
  7. 在下列HTML中哪个是最大标题,在下列的HTML中,哪个是最大的标题?()A.
  8. Win10下安装 Redis
  9. 用Python玩人脸融合,想知道你未来孩子的长相?(附源码)
  10. 谈恋爱可以让生命更富激情