数组的两个特殊性质:1.不能拷贝 2.使用时通常会被转换成指针
所以在数组作为参数时,实际传递的是首地址的指针。
虽然数组会被转换为指针进行传递,但是我们在定义函数的时候依然可以使用数组形参。
void print(const int *); // 一般的指针类型参数 void print(const int []); // 数组类型参数 void print(const int [10]); // 具有长度的数组类型参数,但实际传入的长度是无法被限定的
为了方便大家理解,我做了一些小的修改,这样便于大家对数组参数的特性做一个清晰的认识。
代码如下:
void print(const int *) {}; void printA(const int[]) {}; void printA10(const int[10]) {}; int main() { int i = 0; int j[2] = { 1,2 }; print(&i); printA(&i); printA10(&i); print(j); printA(j); printA10(j); }
代码的编译运行都没有问题,从而直接说明了一个问题,数组参数与指针参数在调用的时候并没有明确的界限。
所以我们需要注意的是,如果采用数组参数进行调用,那么需要我们来保证操作不会超出数组的界限。
保证数组参数的安全调用
使用标记指定长度,如C风格字符串。
void print(const char *) { if (cp) // cp不是空指针 while(*cp) // cp不是0结尾字符 cout << *cp++; // 输出当前字符,并将指针向前移动一位 }
使用标准库规范,传递首尾两个指针,来进行范围的确定。
void print(const int * beg, const int *end) { // 输出beg到end之间的所有元素,不包含end while(beg != end) cout << *beg++ << endl; // 输出当前元素并将指针向前移动一个位置 }
显示的用参数指定数组的大小
void print(const int ia[], size_t size) { for(size_t i = 0; i != size; ++i) { cout << ia[i] == endl; } }
const和数组形参
当函数不需要对参数进行修改时,使用const的指针
数组引用形参
这种定义是被允许的,但是基本不会被使用,定义代码如下
void print(int (&arr)[10]) // 内层的括号不可省略 { for(auto elem:arr) cout << elem << endl; }
传递多位数组
void print(int (*matrix)[10], int rowSize) // 内层的括号同样必不可少 { for(int i = 0; i < 10; ++i) { for(int j = 0; j < rowSize; ++j) { cout << matrix[i][j]; } } }