c语言数组的数量可以是变量吗(数组长度可以是变量吗)
c语言数组的数量可以是变量吗(数组长度可以是变量吗)
2024-06-26 10:39:21  作者:一个限量版  网址:https://m.xinb2b.cn/sport/znz370444.html

关于C 数组提出几点问题:先看下这两段代码,今天小编就来说说关于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,操作超过长度的下标会抛异常有利于开发者及时发现错误。

  • 1米73穿多大的衣服(1米53和1米70的俩人穿同样衣服惊艳出镜)
  • 2024-06-271米53和1米70的俩人穿同样衣服惊艳出镜要知道建筑三原则分别是坚固、实用和美观,而美观则涉及到比例和尺度,与时装有着异曲同工之妙,难怪时尚巨匠香奈儿小姐曾说:“时装是建筑学,它跟比例有关”时装和建筑一样,都有严格的比例要求只要通过面积、长度。
  • 女性什么情况下会得盆腔炎(女性患上盆腔炎)
  • 2024-06-27女性患上盆腔炎盆腔炎是指发生在盆腔的一种炎症疾病,主要包括卵巢炎、宫颈炎和子宫内膜炎等,若没有得到有效治疗会影响女性的生育能力为什么会得盆腔炎?1、没有注意月经期卫生女性在月经期间,子宫内膜处于脱落状态而且宫腔里面。
  • 素媛的一生不能忘的伤痛(豆瓣评分9.2素媛)
  • 2024-06-27豆瓣评分9.2素媛韩国的电影总是敢于挖掘社会最黑暗的那一层面,但是深刻的问题从来得不到解决在观看影片时,那种对黑暗势力的愤怒痛述,往往能够引起观众的共鸣,就像同一公司的员工聚在一起吐槽缺乏人性的公司制度那样的酣畅淋漓的。
  • 张鹤伦第五季欢乐喜剧人(欢乐喜剧人第五季开播)
  • 2024-06-27欢乐喜剧人第五季开播现在娱乐圈中的娱乐节目花样百出,早年间的娱乐节目多以娱乐选秀节目为主,这一类的节目也曾受到很多人的喜爱和追捧,如今社会更新换代的速度比较快,曾红极一时的娱乐选秀节目造成观众的视觉疲劳,现在的喜剧类的节。
  • 开车下雨起雾开什么灯(下大雨开车开什么灯)
  • 2024-06-27下大雨开车开什么灯如何正确的用灯作为影响行车安全的重要因素,其经常性的被提及,但却很少人会认真对待而一旦需要合理开灯的时候,尤其是大雨天气下,多数的车主并不知道到底该开哪个那么下面我们便为大家简要的介绍一下,当我们在大。
  • 长富2号红富士苹果介绍(红富士苹果品种大全)
  • 2024-06-27红富士苹果品种大全出个脑筋急转弯:请问这棵树上富士系品种有几种?5种?6种?哈哈哈,其实正常情况下,一棵树只有一个品种啦~各位请原谅我这个智商余额不足的人不过说起来,红富士苹果在中国大地上居住了近50年了,产生了大量的。
  • 微信小程序免费制作证件照(这个微信小程序一键生成证件照)
  • 2024-06-27这个微信小程序一键生成证件照今天分享一个证件照小程序大家有没有遇到这种情况?突然间就需要一张自己证件照有时候是一寸、两寸,突然又是小二寸有时候是蓝底、红底,突然又是白底总之非常麻烦彩色打印机现在到处都有,打照片的小摊也不难找就是。
  • 手工雪芽茶(雪片茶历经冬季寒风锤炼)
  • 2024-06-27雪片茶历经冬季寒风锤炼秋,缓缓地走过;冬,悄悄地到来!--雪片单枞茶秋高气爽渐渐转入冬季苦寒,单丛茶(雪片)从微微的芽头长成等待采摘的鲜叶!茶园充满着绿色,茶树载满着收获,茶农忙活着采制今年最后的一季茶——雪片茶!单丛茶香。
  • 小学成语歇后语积累(小学语文趣味成语)
  • 2024-06-27小学语文趣味成语一、辩言语,填成语1.很少的几句话:()2.说了很多的话:()3.自己对自己说的话:()4.豪迈雄壮的话:()5.像蜜糖似的话:()6.随口乱说的话:()7.含讽刺意味的风凉话:()8.无根据,恶意中。
  • 一般都是用什么灌肤(深扒火遍全网的)
  • 2024-06-27深扒火遍全网的最近护肤界挂起一股妖风——“灌肤”传说中一次灌肤=1000只水光针=100次针清=50次补水=10次排毒,其效果胜过200次面膜!看到这惊人的数字,吓得小壹赶紧前去一探究竟灌肤是个什么骚操作?先用热毛。
  • 溢组词和拼音(汉字溢组词)
  • 2024-06-27汉字溢组词溢于文辞[yìyúwéncí]情感外露喜悦之情,溢于言表溢言虚美[yìyánxūměi]过甚其辞﹑不符合实际地称美丑声四溢[chǒushēngsìyì]意思是丑恶的名声到处传播形容臭名远扬填街溢巷[t。