c语言数组的数量可以是变量吗(数组长度可以是变量吗)
c语言数组的数量可以是变量吗(数组长度可以是变量吗)
2024-11-22 05:47:56  作者:一个限量版  网址:https://m.xinb2b.cn/life/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英小伙同好友报复情敌据外媒8月20日报道,英国男子因怀孕女友的同事和她调情暧昧,于是约好友一同刺伤女友同事的臀部目前两人被捕,均被判有罪今年1月,威尔特郡科温厄姆市(Covingham,Wiltshire)的艾伦·托德•。
  • 鞋子保养方法(鞋子保养方法分享)
  • 2024-11-22鞋子保养方法分享如果自己不急于穿的鞋,那么鞋内塞入的鞋托或报纸就不必要拿出,这样可以保持鞋的原型,然后再给鞋面上一层薄薄的保护膜,一般是些轻纸,来维持它的美观保养鞋需要长期不断的呵护,要时常检查自己的鞋子,用刷子或清。
  • 韩式铁板烤五花肉做法(韩式烧烤改良版)
  • 2024-11-22韩式烧烤改良版原料:辣白菜100克,五花肉500克调料:色拉油80克,自制烤肉汁100克,葱末、姜末、蒜末各8克秘制烤肉汁配方:白梨5千克,蒜瓣、姜末各2500克,柠檬1500克,放入榨汁机内榨成汁,加入东古一品鲜。
  • 高一数学函数重点题型大题(高一数学函数专题题型归纳)
  • 2024-11-22高一数学函数专题题型归纳第一节:函数的概念及表示题型一:判断图像或者对应关系是否为函数题型二:区间的表示题型三:求函数值题型四:同一函数的判断第二节:函数的定义域题型一:具体函数的定义域题型二:抽象函数的定义域题型三:已知定。
  • 买房子贷款时可以单独用公积金吗(相关规定介绍)
  • 2024-11-22相关规定介绍买房子贷款时可以单独用公积金原本使用商业贷款购房的消费者,可以转成住房公积金贷款(即住房公积金转按揭贷款)据了解,申请个人住房公积金转按揭贷款必需符住房公积金贷款管理实施方法的有关规定,且贷款额度不得。
  • 海贼王克洛克达尔最新消息(海贼王最可怕的谣言)
  • 2024-11-22海贼王最可怕的谣言早在伊万科夫出现之前就有人猜测克洛克达尔是女人,一个原因是克洛克达尔手上戴满戒指,唯独无名指上没戴,这个位置是戴结婚戒指的阿拉巴斯坦有一头叫睫毛的骆驼只驼女人,但它却驼过老沙巴洛克工作社的命名,一男一。
  • 营销策略和技巧(营销人最值得关注的九大营销策略)
  • 2024-11-22营销人最值得关注的九大营销策略当我们开始诊断企业现状时,制定了目标,营销的策略也随之提出,那么我们常见的策略有哪些呢?1、情感营销策略:情感营销就是把消费者个人情感差异和需求作为企业品牌营销战略的核心,通过借助情感包装、情感促销、。
  • 刘德华被告怎么回应的(最新刘德华回应)
  • 2024-11-22最新刘德华回应来源:澎湃新闻澎湃新闻记者杨慧米5月21日,奥迪汽车与刘德华合作的宣传短片《今日小满,人生小满就好》发布名人与知名品牌的组合,加上视频上佳的文案,迅速在网络上刷屏没想到不到一天时间,视频就翻车了当日晚。
  • 网络上吃瓜是什么意思
  • 2024-11-22网络上吃瓜是什么意思吃瓜,网络流行词,其含义为在网络环境中,用来表示一种不关己事、不发表意见仅围观的状态普通网友们常常戏称自己为“吃瓜群众”而“瓜”则表示某个热点八卦事件。
  • 江西保护濒危植物(江西首次发现珍稀濒危植物二脊沼兰)
  • 2024-11-22江西首次发现珍稀濒危植物二脊沼兰近日,江西省赣州市石城县赣江源国家级自然保护区工作人员在开展植物资源调查时,发现一种罕见植物,经专家鉴定为珍稀濒危植物二脊沼兰,这是江西省境内首次发现二脊沼兰二脊沼兰属兰科沼兰属,是地生草本植物,对自。