C++学习笔记-函数数组传参
2014-11-04 20:20
387 查看
问题描述:
int size_n;
int a[]={1,3,0,5,-1,6};
size_n=sizeof(a)/sizeof(a[0]);
定义一个函数void solve(int *a,int size_n);此时需要注意的是数组a的传递方式,对比下引用和指针的方式。
1、函数调用如下所示
int size_n;
int a[]={1,3,0,5,-1,6};
size_n=sizeof(a)/sizeof(a[0]);
solve(a,size_n);
函数定义如下所示:
方式1:
void solve(int a[],int size_n);//可以通过
方式2:
void solve(int a[6],int size_n);//可以通过
方式3:
void solve(int *a,int size_n);//可以通过
方式4:
void solve(int &a,int size_n);//无法通过编译。 这里需要的a是一个int,不是int*,也不是int[]更不是int*&。
方式5:
void solve(int (&a)[6],int size_n);//可以通过,必须确定数组长度。
数组形参定义为非引用时:传递的数组实参转换为指针;
数组形参定义为引用时:编译器不会将数组转换为指针,而是传递数组的引用本身。也就是说,数组的长度不可省略,编译器将检查传入函数的实际数组参数的长度和函数的形式参数的长度是否匹配。
想接收任意长度的数组,应当使用模板函数。如下所示:
template<int size_n>
void fun(int (&a)[size_n],int size_n)
{ 对数组的操作}
函数调用方式一样。
2、数组形参小结
2-1:数组形参
数组形参会被弱化为指针,所以处理数组的函数通常通过指向数组中元素的指针来处理数组。
上面3种定义等价,形参类型都是int *,通常使用第1种,即上述例子中的方式3。第2种形式虽然看起来更直观,但容易引起误解,因为函数操纵的毕竟不是数组本身,而是指向数组元素的指针。第3种形式的数组长度是被忽略的,这里的10并无实际的约束作用,在printValues内部不应依赖这个数组长度做事情。所以,这个数字并不重要。 和其他类型一样,形参也可以是数组的引用。这时编译器不会将数组实参转换为指针,而是传递数组的引用本身。数组大小成为形参和实参类型的一部分。编译器检查数组实参的大小与形参的大小是否匹配。
这个版本的printValues只严格接受含有10个ints的数组,所以在printValues函数体内依赖数组大小也是安全的。&arr两边的括号是必须的,否则int &arr[10],会被当做是含有10个引用的数组。
2-2:非形参的数组引用。
至于数组引用的使用,可以参见下面程序。
int k[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int &b=k;
程序会直接报错!无法从“int [10]”转换为“int &”。可以与函数调用时引用数组作为形参进行对比。
int size_n;
int a[]={1,3,0,5,-1,6};
size_n=sizeof(a)/sizeof(a[0]);
定义一个函数void solve(int *a,int size_n);此时需要注意的是数组a的传递方式,对比下引用和指针的方式。
1、函数调用如下所示
int size_n;
int a[]={1,3,0,5,-1,6};
size_n=sizeof(a)/sizeof(a[0]);
solve(a,size_n);
函数定义如下所示:
方式1:
void solve(int a[],int size_n);//可以通过
方式2:
void solve(int a[6],int size_n);//可以通过
方式3:
void solve(int *a,int size_n);//可以通过
方式4:
void solve(int &a,int size_n);//无法通过编译。 这里需要的a是一个int,不是int*,也不是int[]更不是int*&。
方式5:
void solve(int (&a)[6],int size_n);//可以通过,必须确定数组长度。
数组形参定义为非引用时:传递的数组实参转换为指针;
数组形参定义为引用时:编译器不会将数组转换为指针,而是传递数组的引用本身。也就是说,数组的长度不可省略,编译器将检查传入函数的实际数组参数的长度和函数的形式参数的长度是否匹配。
想接收任意长度的数组,应当使用模板函数。如下所示:
template<int size_n>
void fun(int (&a)[size_n],int size_n)
{ 对数组的操作}
函数调用方式一样。
2、数组形参小结
2-1:数组形参
数组形参会被弱化为指针,所以处理数组的函数通常通过指向数组中元素的指针来处理数组。
void printValues(int *) { /* … */ } void printValues(int []) { /* … */ } void printValues(int [10]) { /* … */ }
上面3种定义等价,形参类型都是int *,通常使用第1种,即上述例子中的方式3。第2种形式虽然看起来更直观,但容易引起误解,因为函数操纵的毕竟不是数组本身,而是指向数组元素的指针。第3种形式的数组长度是被忽略的,这里的10并无实际的约束作用,在printValues内部不应依赖这个数组长度做事情。所以,这个数字并不重要。 和其他类型一样,形参也可以是数组的引用。这时编译器不会将数组实参转换为指针,而是传递数组的引用本身。数组大小成为形参和实参类型的一部分。编译器检查数组实参的大小与形参的大小是否匹配。
#include <iostream> using namespace std; void printValues(int (&arr)[10]) { for (size_t i = 0; i != 10; ++i) cout << arr[i] << endl; } int main() { int i = 0, j[2] = {0, 1}; int k[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; printValues(&i); // error: argument is not an array of 10 ints printValues(j); // error: argument is not an array of 10 ints printValues(k); // ok: argument is an array of 10 ints return 0; }错误如下所示:
这个版本的printValues只严格接受含有10个ints的数组,所以在printValues函数体内依赖数组大小也是安全的。&arr两边的括号是必须的,否则int &arr[10],会被当做是含有10个引用的数组。
2-2:非形参的数组引用。
至于数组引用的使用,可以参见下面程序。
int main() { int i = 0, j[2] = {0, 1}; int k[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int (&b)[10]=k; printValues(b); // printValues(k); // ok: argument is an array of 10 ints return 0; }而不能写成如下的
int k[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int &b=k;
程序会直接报错!无法从“int [10]”转换为“int &”。可以与函数调用时引用数组作为形参进行对比。
相关文章推荐
- C++学习笔记七之使用数组区间的函数
- C/C++学习笔记12:数组作为函数参数
- c++ 模板学习笔记:函数模板实现数组通用排序和遍历打印(权哥)
- C++学习笔记(三)--函数参数,数组函数,指针和const,二维数组函数,递归,函数指针
- C++ 学习之函数传参2:vector和数组传参
- C++学习笔记六之函数如何使用指针来处理数组?
- c++学习笔记(七):函数返回数组
- C++基础教程 学习笔记(二) 数组、字符串和指针
- C++学习笔记(四)——数组和指针
- C++学习笔记--数组
- C++数组类型学习笔记
- C/C++学习笔记1 - 深入了解scanf()/getchar()和gets()等函数(原创)
- C/C++中关于地址、指针和引用变量的学习笔记(四) : 函数
- C/C++学习笔记:指针与数组
- C++ 学习之函数传参1:引用传参和非引用传参
- [C++学习笔记]自定义函数的传值方法
- C/C++中关于地址、指针和引用变量的学习笔记(二) : 数组
- JavaScript学习笔记 6-循环、数组和函数 Loops , Arrays and Function
- c++学习笔记2——指向字符串的指针数组?
- 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 习题2.8 随机数组的三种生成算法(补) 将bash的实现翻译成比较纯正的bash风格