The symbolic name for “data” that passes into a function.
传递给函数的“数据”的符号名称。
函数的参数是变量名,用来把数据从调用函数的环境传递到被调用的环境中去,参数传递的过程叫做传参。
传参的两种方式Two ways to pass into a function:
- Pass by value
- Pass by reference
Pass by value: fundamental type(基本数据类型)
The parameter is a copy of the original variable
int foo(int x)
{ // x is a copy
x += 10;
return x;
}
int main()
{
int num1 = 20;
int num2 = foo( num1 );
return 0;
}
基本数据类型作为函数参数的时候,传递的是数据的拷贝。num1
是作为参数传递给函数foo
,函数中的x
是一个局部变量,是num1
的拷贝,局部变量x
的值在foo()
内部执行加10操作,但是num1
的值不会改变。函数中return的值也是一个拷贝,将拷贝的值赋值给num2
。
Pass by value: pointer
What’s the difference?和上面代码会有什么差异呢?
int foo(int * p)
{
(*p) += 10;
return *p;
}
int main()
{
int num1 = 20;
int * p = &num1;
int num2 = foo( p );
return 0;
}
It still is passing by value (the address!)
A copy of the address
传递给函数的是num1
所在的地址,然后将拷贝之后的地址传递给函数,在函数中,该地址的值执行加10操作,就是执行了num1中的内容。
#include <iostream>
using namespace std;
int foo1(int x)
{
x += 10;
return x;
}
int foo2(int *p)
{
(*p) += 10;
return *p;
}
int main()
{
int num1 = 20;
int num2 = foo1(num1);
cout << "num1=" << num1 << endl;
cout << "num2=" << num2 << endl;
int *p = &num1;
int num3 = foo2(p);
cout << "num1=" << num1 << endl;
cout << "*p=" << *p << endl;
cout << "num3=" << num3 << endl;
return 0;
}
// num1=20
// num2=30
// num1=30
// *p=30
// num3=30
Pass by value: structure
How about structure parameter?
struct Matrix
{
int rows;
int cols;
float * pData;
};
// 找矩阵中的最大值
float matrix_max(struct Matrix mat)
{
float max = FLT_MIN;
for(int r = 0; r < mat.rows; r++)
for (int c = 0; c < mat.cols; c++)
{
float val = mat.pData[ r * mat.cols + c];
max = ( max > val ? max : val);
}
return max;
}
// 实例化一个Matrix,行列为3,4,
Matrix matA = {3,4};
matrix_max(matA);
mat也是一个变量,当被调用时,其也会被拷贝一份,传入函数进行调用,同之前两种情况相同。如果通过pData的地址修改了内容,matA的成员变量虽然没有被修改,但是pData指向的数据被修改了。
Now, pass by value.
But if the structure is a huge one, such as 1K bytes.每一次的参数调用都要拷贝一份,这个内存消耗就很大了。
A copy will cost 1KB memory, and time consuming to copy it.
那就是引用!!!