上回说到C指针的定义和运算符"*""&",这次来谈谈C函数的传值引用以及著名的const.
考虑一段典型的函数引用:
- int foo(int x, int y)
- {
- int tmp = x;
- x = y;
- y = tmp;
- }
- int main()
- {
- int a = 2;
- int b = 4;
- foo(a,b);
- return 0;
- }
函数foo将x,y值变换,调用foo(a,b)的时候,编译器会在堆栈中复制一份a,b的拷贝,然后把这个拷贝传递给foo供其使用.这样的好处是遵循了强制访问控制权限:foo只能改变a,b拷贝的值,不能改变传值给foo的a,b本身!但是在某些条件下,我们需要修改传值本身的参数,例如在排序当中,我们就需要可以在一个类似于swap的函数中访问调用它的父函数的局部变量.
这个时候我们就需要使用传引用调用,即传递指针(地址)给函数,类似的改写上面那个函数
- int foo (int *x , int *y)
- {
- int tmp = *x;
- *x=*y;
- *y=tmp;
- }
调用foo的时候这样foo(&a,&b),传递指针的好处在于可以灵活的处理逻辑和减少堆栈的开支,提高效率.
但是我们知道指针往往会导致其他一些灾难性的问题,比如修改了某些关键参数等,咋整呢?
使用const!简单的来说const限定符通知编译器禁止修改某些特定变量。
如果const关键字不涉及到指针,我们很好理解,下面是涉及到指针的情况: int b = 500;
const int* a = &b; [1] 指向常量的变量指针,地址可以变化
int const *a = &b; [2] 同上
int* const a = &b; [3] 指向变量的常量指针,值可以变化,例如数组名
const int* const a = &b; [4] 指向常量的常量指针
我们可以参考《Effective c++》Item21上的做法,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。