问题描述
今天在做《c++ primer》上的习题的时候,遇到了一个小问题。
原始函数如下:
void output1(int a[], int len) {
int ia[len];int cnt = 0;
for (int &x : ia)
{
x = *(a + cnt);
++cnt;
}
for (int i : ia)
{
cout << i << " ";
}
cout << endl;
}
数组a为一维整型数组,利用函数实现元素的依次输出。但是编译器在for (int i : a)
处提示错误,int*
不能用在此处。细想之前书中的细节,我明白了,c++倾向于将数组名直接当作数组第一个元素的首地址,即数组作为函数的参数,实际是传址操作。上网查阅,看到这篇博客;也印证了这一想法。
探讨
借此,整理一下,C++中,数组作为函数参数的一些注意事项,包括多维数组;
1. 一维数组
- 在函数中传递数组时,如上的调用,实际只传递了数组的首地址,不能将数组的长度信息传递出去,因此,解决方案就是,将数组的长度信息传入函数,如下时是我修改后的输出函数:
void output1(int a[], int len) {
int ia[len];int cnt = 0;
for (int &x : ia)
{
x = *(a + cnt);
++cnt;
}
for (int i : ia)
{
cout << i << " ";
}
cout << endl;
}
调用函数语句如下`output1(ia, sizeof(ia)/ sizeof(ia[0]))`;利用`sizeof()`函数实现对数组大小的求解,之后将长度值传入函数,那么函数中即可直到数组的边界,进行进一步的操作。
2. 二维数组
– 《C++ primer》中讲解,c++中,二维数组实际是一种特殊的一维数组,即每一个元素不是一个数,而是一个数组。编译器在对数组进行处理时,a[3][4]中的一个元素a[i][j]实际被认为是(a+i*4+j),而在内存中,数据实际是以行列的顺序一维排列,因此,如果形参中没有包含数组的列信息,函数将无法正确调用数组,所以与一维数组类似,最好在函数定义时,明确其大小空间,如下:
void fun(int a[][4]);
void fun(int a[3][4]);
数组的行数,不一定需要特别指出,但是列数不能忽略,如下的定义就是错误的
void fun(int a[][]);
总结
- 这么一通下来,我觉得C++中并没有很好的支持数组的操作,函数调用的方式不知道为什么不能直接传入整个数组,想起知乎上一位网友的说法,在C++中,能用string尽量不用char,能用vector尽量不用数组,当时不太明白,现在想想,的确是这么回事。