赞
踩
调用时,将实参的值传递对应的形参,即为值传递。由于形参有自己独立的存储空间,又作为函数的局部变量使用,因此在函数中对任何形参值得修改都不会改变实参变量的值。简单的看一个例子:
void swap(int a,int b){
int c=a;
a=b;
b=c;
cout<<a<<b;
}
引用传递时需要借助取址运算符&,是一种特殊的变量,能够获取变量的地址(变量具有地址和本身值的二值属性,这是很容易让人忽视的地方,而取值运算符(*)能够获取给定地址中的值)。当定义一个引用时,其实是获取目标变量的地址,引用并不分配独立的内存空间,它与目标变量公用其内存空间,当定义一个引用时,如果该引用不是用作函数的参数或者返回值,则必须提供该引用的初始值(即必须提供引用的目标变量名)如图:
void swap(int &a,int &b){
int c=a;
a=b;
b=c;
cout<<a<<b;
}
关于用数组作为形参时,不论是字符串数组还是其他类型数组,在c/c++中只能使用引用传递,假若能用值传递,如果数组很大,再复制过来,就要开辟很多内存空间,而且很耗时间。传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址。
void func(int array[10])
void func(int array[])
void func(int *array)
所以以上三种函数声明完全等同。
实际情况是,数组做参数,完全无法按值传递。这是由C/C++函数的实现机制决定的。
这里举一个使用泛函模板template进行数组引用传递的例子:
#include<iostream>
#include<string>
using namespace std;
//排序数组
template<typename T> //定义一个泛函模板
void sort1(T a[],int len){ //排序函数,从小到大
for(int i=1;i<len;i++)
for(int j=0;j<i;j++){
if(a[i]<a[j]){
T c=a[i];
a[i]=a[j];
a[j]=c;
}
}
}
//泛函打印函数
template <typename T>
void print(T a[],int len){
for(int i=0;i<len;i++){
cout<<a[i]<<',';
}
cout<<endl;
}
int main(){
//泛函的使用
//自动调用,编译器根据a和b的类型来推导
int a=0,b=1;
swap1(a,b);
//显示调用,告诉编译器,调用的参数是float类型
float c=0,d=1;
swap1<float>(c,d) ;
//cout<<c<<d<<endl;
int e[5] = {5, 3, 2, 4, 1};
sort1(e, 5); //自动调用,编译器根据a和5的类型来推导
print<int>(e, 5); //显示调用,告诉编译器,调用的参数是int类型
string s[5] = {"Java", "C++", "Pascal", "Ruby", "Basic"};
sort1(s, 5);
print(s, 5);
return 0;
}
输出结果:
1,2,3,4,5,
Basic,C++,Java,Pascal,Ruby,
总结一下:c/c++中数组使用引用传递,而单变量可以使用值传递和引用传递。最后,本篇博客并没有涉及字符及字符串的传递规则,其内容同样较大,后面将补上。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。