1. 我可不可以int len=5; int arr[len]; 这样写呢?
不能,[]里面不能是变量或者含有变量的表达式。但真的不可以吗?
首先我们看看为什么不可以,在C语言里,所有变量空间都是在程序运行之前向系统申请的,除了动态申请malloc什么的之外,也就是说,变量定义的数组空间大小是不确定的,所以定义不了,关键就是在于空间是在程序运行之前开辟的。如果我们要在C语言里定义一个可变长度的数组,必须用malloc函数动态开辟,例如
int* const a = (int*)malloc(sizeof(int)*n);
这样,比较麻烦。但是,你现在用最新版的gcc编译一下,发现int arr[len]是可以通过的!为什么呢?因为在C99标准中添加的这一特性,在C89是不支持的。但是目前的编译器都不怎么愿意支持C99规范,例如MSVC就不支持(理由是windows平台下开发更多用C++而并非用C语言,这也是事实,C语言现在多用于嵌入式,而嵌入式用旧标准就已经足够使用了),但是gcc是支持了99%的C99规范,甚至包括for循环里定义变量,就是for(int i=0;;)(注意这是C语言!),emmmm,用不用随你,建议A题时随便用,工程时不要用。
至于C++,道理与C语言相同,只不过有更方便的new,你干嘛要纠结新标准呢?
那么问题来了,如果我定义一个二维数组,采取int arr[m][n].......
我的回答是,不要玩火,虽然它还是支持的。。。但是,强烈建议第二位是个固定常量,不得不说现在的编译器是真的先进,把之前千叮咛万嘱咐的易错点全部给打补丁了。
2. 定义一个数组同时给它初始化?
甭管是C语言还是C++,你都不能让这个数组便捷的同时初始化为除0之外的任何数字,什么意思呢,就是如果你这样写:
int arr[100] = {1};
这么写的含义不是每个单元都初始化为1,而是第一个单元初始化为1,其他初始化为0,还有一个函数,就是memset,它也是只能全部置0,因为它是按照字节赋值,而且要引用头文件string.h,当然,如果你是一个字符数组那是可以便捷赋值的,但要不是字符数组,就不要用这个memset,实际上,我更推荐自己for循环。
动态初始化一个数组呢,对于malloc还是new,都是不初始化的,这是为了效率,但是这样new是可以初始化的:
bool* array = new bool[10](); //初始化为0
在最后多了一个括号,这样就能初始化为0了,至于初始化成别的数字,抱歉,自己for循环吧。
接下来比较难的,用new定义一个二维数组,这么创建
int (* array2D)[5] = new int[n][5]; // 仍然强烈建议第二位是个常量
不是强烈建议,而是必须这么做,因为第二位是变量编译器会报错。但是你用int arr[m][n]就不会报错你说这世道啊~
如果你要用int arr[n][m];这里有一个bug你要注意一下,它不能用int arr[n][m]={{0}};来初始化,这样初始化是失败的(但是值得注意的是,int arr[n]={0}是初始化成功的),自然也不能放到全局变量上,n未定义呢。你与其花个二重循环来初始化这个数组,还不如用int (* array2D)[5] = new int[n][5]();来的快呢。。。
那么,我说,我想用new一个二维数组,第二位也是一个变量,可不可以呢?
其实这种情况还是很常见的,虽然二维数组不允许这样做,但是直接可以用一个一维数组代替二维数组也是没有问题的,如果就是想要一个动态二维数组,可以这么办:
int **a = new int* [m] //分配一个指针数组,将其首地址保存在a中 、
for(int i = 0; i < m; i++) //为指针数组的每个元素分配一个数组
a[i] = new int [n];
相当于产生了一个二维数组 a[m][n]了。
因此,用一个一维数组代替二维数组是最佳选择。
当然你也可以用vector。