c语言数组的数量可以是变量吗(数组长度可以是变量吗)
c语言数组的数量可以是变量吗(数组长度可以是变量吗)
2024-11-22 12:32:59  作者:一个限量版  网址:https://m.xinb2b.cn/tech/znz370444.html

关于C 数组提出几点问题:先看下这两段代码,今天小编就来说说关于c语言数组的数量可以是变量吗?下面更多详细答案一起来看看吧!


c语言数组的数量可以是变量吗

关于C 数组提出几点问题:

预备

先看下这两段代码

变量作为数组的长度可行吗?

#include <iostream>using namespace std;void func(int num) { int array[num]; // num > 0 cout << "num " << num << endl; cout << "sizeof array " << sizeof(array) << endl; array[0] = 20; cout << "array[0] " << array[0] << endl;}int main() { func(6); return 0;}

输出:

num 6sizeof array 24array[0] 20

访问超过长度的数组下标的值会发生什么?

#include <iostream>using namespace std;void func() { int array[10]; array[3] = 1; array[20] = 3; cout << "sizeof array " << sizeof(array) << endl; cout << "array[3] " << array[3] << endl; cout << "array[20] " << array[20] << endl;}int main() { func(); return 0;}

输出:

sizeof array 40array[3] 1array[20] 3

分析

首先分析问题1,我们平时看书学习过程中总看见说C 的数组长度一定要是常量且不能是变量,很多资料需要在编译期确定栈帧的大小,如果是变量就不能在编译器确定栈帧大小,但上述代码为什么可以正常运行呢?光看不如实践,先看这样一段代码:

#include <iostream>using namespace std;void func2() { int a; int b[4]; int c; cout << "func2a address " << &a << endl; cout << "func2b address " << &b << endl; cout << "func2c address " << &c << endl; // func1();}void func3(int num) { int a; int b[4]; int c; cout << "func3a address " << &a << endl; cout << "func3b address " << &b << endl; cout << "func3c address " << &c << endl; func2();}void func4(int num) { int a; int b[4]; int c; cout << "func4a address " << &a << endl; cout << "func4b address " << &b << endl; cout << "func4c address " << &c << endl; func3(num);}int main() { func4(5); return 0;}

输出:

func4a address 0x7ffeb675f418func4b address 0x7ffeb675f420func4c address 0x7ffeb675f41cfunc3a address 0x7ffeb675f3c8func3b address 0x7ffeb675f3d0func3c address 0x7ffeb675f3ccfunc2a address 0x7ffeb675f378func2b address 0x7ffeb675f380func2c address 0x7ffeb675f37c

再看这段代码:

void func2() { int a; int b[4]; int c; cout << "func2a address " << &a << endl; cout << "func2b address " << &b << endl; cout << "func2c address " << &c << endl; // func1();}void func3(int num) { int a; int b[num]; int c; cout << "func3a address " << &a << endl; cout << "func3b address " << &b << endl; cout << "func3c address " << &c << endl; func2();}void func4(int num) { int a; int b[4]; int c; cout << "func4a address " << &a << endl; cout << "func4b address " << &b << endl; cout << "func4c address " << &c << endl; func3(num);}int main() { func4(100); return 0;}

输出:

func4a address 0x7ffff2c76568func4b address 0x7ffff2c76570func4c address 0x7ffff2c7656cfunc3a address 0x7ffff2c76510func3b address 0x7ffff2c76360func3c address 0x7ffff2c76514func2a address 0x7ffff2c76328func2b address 0x7ffff2c76330func2c address 0x7ffff2c7632c

func4a - func3a = 88func3a - func2a = 488从上面两段代码其实可以看出C 是支持变量长度的数组的,说不支持的那是很古老的编译器,在如下链接中也可以找到答案。https://c-for-dummies.com/blog/?p=3488https://www.drdobbs.com/the-new-cwhy-variable-length-arrays/184401444https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard备注:尽管C 目前支持变量长度的数组,但是不建议使用,因为数组使用的是栈内存,栈内存是有大小限制的,一般是8192字节,既然长度是变量,那就可能是任何值,就有可能超过8192,这样就会stack overflow,所以动态内存最好使用堆内存。

再分析问题2:操作超过数组长度的内存会发生什么?看下面这段代码:

#include <iostream>using namespace std;void func() { int array[10]; array[3] = 1; array[40] = 3; cout << "sizeof array " << sizeof(array) << endl; cout << "array[3] " << array[3] << endl; cout << "array[40] " << array[40] << endl;}int main() { int a[200]; for (int i = 0; i < 200; i) { a[i] = 100; } for (int i = 0; i < 200; i) { cout << a[i] << " "; } cout << endl << "=====================" << endl; func(); cout << "=====================" << endl; for (int i = 0; i < 200; i) { cout << a[i] << " "; } cout << endl << "=====================" << endl; return 0;}

输出:

root@3eaa9392a3d9:/ubuntu/test_dir# ./a.out100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100=====================sizeof array 40array[3] 1array[40] 3=====================100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 3 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100=====================

看代码输出,在函数内操作超过数组长度的内存没有什么影响,但是它却导致了上一级的数组a[200]里的内容被改变,因为数组使用的是栈内存,经过问题1的代码输出以及分析可以看出,栈帧内存是向下增长的,代码中操作了超过数组长度的内存地址,就影响到了之前栈帧的内存数据,导致之前栈内存数据出现错误,可能就会引发大bug。

总结

C 中数组长度可以是变量,但是不建议使用,因为数组使用的是栈内存,变量可以是个比较大的数,这样会导致stack overflow,建议使用堆内存。

操作超过数组长度的内存可以编译通过且表面上看不出来问题,但是会导致栈内存出现脏写,最终可能会引发难以排查的bug,建议数组使用std::array,操作超过长度的下标会抛异常有利于开发者及时发现错误。

  • 白吉馍口感(想吃白吉馍不用买)
  • 2024-11-22想吃白吉馍不用买大家好,我是阿飞,关注阿飞有更多的家常菜供大家参考!白吉馍皮薄松脆,内心软绵,夹上腊汁肉几天不吃想的慌白吉馍又称腊汁肉夹馍想起以前走在街上每次看见推车卖白吉馍的就忍不住想买个尝尝,脆脆的外皮,肥而不腻。
  • 农村少年宫活动安排(全程免费惠东县乡村)
  • 2024-11-22全程免费惠东县乡村-好好学习天天向上-2022年惠东县新时代文明实践中心乡村“复兴少年宫”暑假公益活动✦免费活动!速来报名!✦想要假期过得好玩又有意义?这个夏天惠东县新时代文明实践中心乡村“复兴少年宫”精心策划了有趣有。
  • 地蜡的使用方法(地蜡的使用方法有什么)
  • 2024-11-22地蜡的使用方法有什么先采用专业工具清除地板表面上的附着污垢、胶渍等其他粘物用地面清洗机、配兑相应清洗剂、如有旧蜡层需要用起蜡水将旧蜡驱除方可作业针对不同的地面材质,使用不同的蜡水,一般有液体蜡、固体蜡、水晶蜡、喷蜡将蜡水。
  • 下定决心分手的说说
  • 2024-11-22下定决心分手的说说本想把星星摘给你,但想想还是算了,我够得着星星,够不着你跟自己说声对不起,捡起自尊,高傲的走下去!从此以后,一别两宽!。
  • 冰箱异常响动(冰箱异常响动原因)
  • 2024-11-22冰箱异常响动原因冰箱放置不平在放置冰箱的时候,基本上都会选择两个地方,一个是厨房,一个是餐厅,不管摆在哪里都需要注意,冰箱要距离墙面一定距离,而且很重要的一点就是让冰箱保持水平,而且不会摇晃如果冰箱没有放平,那么压缩。
  • 商业计划书完整的方案模板(企业商业计划书)
  • 2024-11-22企业商业计划书本商业计划书模板,参照了多份国内外经典的成功实现融资的商业计划书内容、国内外权威投资人士总结的有关商业计划书的撰写要求(含中英文版),同时还紧密结合中国中小企业发展的实际需求,不仅列出了商业计划书的主。
  • 孕妇吃木耳的好处(孕妇吃木耳的好处有哪些)
  • 2024-11-22孕妇吃木耳的好处有哪些在怀孕的时候是可以吃黑木耳的,部分女性在怀孕早期会有头晕的现象,头晕是缺铁性贫血的一个重要标志,而适当的吃一些黑木耳,就能够预防贫血,或者是治疗缺铁性的贫血,而且黑木耳没有任何的毒副作用是一种非常好的。
  • 喜字剪纸怎么剪出来(自己动手剪个四喜字剪纸)
  • 2024-11-22自己动手剪个四喜字剪纸我们都有一个美好的愿望,希望能够好事连连,喜事连连,结婚办喜事的时候,自己可以剪一个喜事连连剪纸,寓意喜事像水波一样,一波刚去,一波又来,这么好的兆头,相信是我们大家都想要的今天分享就是喜事连连剪纸,。
  • 炸油条简易方法(油条的做法介绍)
  • 2024-11-22油条的做法介绍原料:面粉300克,温牛奶250毫升,泡打粉1小勺,小苏打半小勺,盐1小勺,植物油25克做法:把泡打粉、小苏打和盐用温牛奶化开,和面粉和好揉匀,再倒入少许植物油,揉光滑,盖上盖子放在常温下一夜(注意不。
  • 陈松伶电视剧粤语全集(第一集就告诉你凶手)
  • 2024-11-22第一集就告诉你凶手大家好,我是汤粉嘀哒喜欢追剧就是我,我就喜欢追电视剧,还有电影和综艺不知道最近大家是否沉浸在剧荒的状态呢?特别是港剧迷们,深有体会话说,小编我追完张卫健主演的《大帅哥》之后,就沉浸在赵丽颖、冯绍峰的《。
  • 微博忘记登录名和密码怎么找回
  • 2024-11-22微博忘记登录名和密码怎么找回/4单击忘记密码打开微博登录页面,选择忘记密码2/4点击手机验证进入后选择其他方式验证,优先使用手机号来验证3/4输入验证码按照提示输入手机号,发送验证码4/4点击登录按照验证码登录后,重新修改帐号密。