【转】关于数组初始化

来源:https://www.icourse163.org/learn/ZJU-199001?tid=1002774001

一般初始化数组可能这样的:

int arr[10] = {1};

这样的结果是创建一个长度为10(包含10个元素,下标从0~9)的数组,其中第一个元素是1,后面的九个元素是0。
有的时候我们会碰到一个问题,开始并不知道有多少个元素,需要用户进行输入,那解决方案是,比如开一个足够大的数组,并对用户的输入进行检测,如小于这个数组可容纳的范围,便继续操作,如果大于,则提醒用户重新输入。C99标准给我们提供了另一个解决方案,可以让用户先输入元素的个数,再创建可容纳这么多元素的数组,比如用户输入10,那就创建一个大小为10的数组。

int n;
scanf("%d", &n);
int array[n];

接下来的问题是如何初始化,有同学提出在创建的时候就初始化。

int n;
scanf("%d", &n);
int array[n] = {0};

这样编译会失败,为什么呢?因为在编译的时候,编译器并不知道n的大小,n的大小是需要等待用户进行输入的,也就是说在运行时刻才知道。编译器的错误提示是:

[Error] variable-sized object may not be initialized

意思是可变长度的数组不能被初始化。编译器在编译时刻不知道数组的大小是多少,不知道开多大的空间,自然会抱怨。
所以我们换一种写法:

int n;
scanf("%d", &n);
int arr[n];
for (int i=0; i<n; ++i) {
    arr[i] = 0;
}

有同学问为什么for loop就可以了,因为在程序运行的时候,先执行用户输入n,然后创建大小为n的数组,待for loop的时候,是知道具体大小的,就可以对每个元素进行逐一赋值操作了。除了使用for loop,还可以用memset的方式。

memset(arr, 0, sizeof(arr));

然后有同学会问,你说的不能通过编译的情况,在Dev C++里是能通过编译的,这是为什么?
在Dev C++默认保存文件的时候被存为.cpp,编译时会按照C++的编译器进行编译,C++在处理的时候有些不同,假设我们预设数组至少有3个元素,但用户输入数组元素是2个。测试代码如下:

int n;
scanf("%d", &n);
int arr[n] = {1,2,3};

用户输入2。
2

terminate called after throwing an instance of 'std::bad_array_length'
  what():  std::bad_array_length

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

可见C++对动态数组的处理方式是编译通过,在运行时等待用户输入后,检查用户输入的大小是否合适,然后再初始化。
cpp_reference
当出现以下3种情况时,会报bad_array_length
①长度是负数
②数组大小超过可定义的最大值
③初始化列表中的元素个数超过了数组最大可容纳的元素个数
前面的这段代码就属于第3种错误情形。
也有同学问,为什么在线开发环境里,这样的写法是可以的。因为在线环境是翁老师的学生自己做的,处理动态数组时方式和gcc不一样。
另一个问题是,后面介绍了const,说明数值是不能改变的,那么为什么下面的代码不能通过编译。

const int n = 10;
int arr[n] = {0};

同样报错:

扫描二维码关注公众号,回复: 1453859 查看本文章
[Error] variable-sized object may not be initialized

不是说const修饰的变量不能被改变吗?这里需要注意C和C++的不同,C语言里面的const是值不能改变的变量,并非常量。而C++中的const是真正意义上的constant,上面这段代码可以通过编译

猜你喜欢

转载自blog.csdn.net/qq_36589706/article/details/80409889