C 知识量:16 - 74 - 317
使用带参数的函数时,传递参数时需要确认是传递某个类型的值,还是传递指向某个类型的指针。一般情况下,只需要传递数值,只有当需要在函数内部影响外部传递的值时,才需要传递指针。
对数组而言,只能传递指针。如果不是这样,就需要分配足够的空间来储存原数组的副本,再把原数组的所有数据拷贝到新数组中,这样的代价太大了,因此,传递指针的效率更高。
问题在于,如果传递的是指针,那么在函数内部对参数(数组元素值)的修改就会直接影响原数组,因此,需要通过某种方式对数据数据进行保护。
可以在函数原型和函数定义中使用const关键字来起到保护数组数据的作用,例如:
/*函数原型*/ int sum(const int array[], int n); /*函数定义*/ int sum(const int array[], int n) { int i; int total = 0; for (i = 0; i < n; i++) total += array[i]; return total; }
以上代码中的const关键字表明,该函数不能修改array指向的数组中的内容。这样使用const并不是要求原数组是常量,而是该函数在处理数组时会将其视为一个常量,不可更改,这样就可以对数组起到保护作用。
可以创建const数组、const指针和指向const的指针。
1、指向const的指针。指向const的指针不能用于改变值。例如:
int arr_int[3] = {100, 200, 300}; const int *p = arr_int;
第二行代码将p指向的int类型的值声明为const,这表明不能使用p来更改它所指向的值,比如:
*p = 400; //不允许 p[2] = 400; //不允许 arr_int[2] = 400; //允许,因为arr_int没有被const限定
以上代码中,无论是使用指针表示法还是数组表示法,都不允许使用p来修改它所指向数据的值。但是,可以将p指向别处,例如:p++;是允许的。一般的,指向const的指针通常用于函数的形参中,表明该函数不会使用指针改变数据。
关于指针赋值和const需要注意以下规则:
把const数据或非const数据的地址初始化为指向const的指针或为其赋值是合法的。例如:
int r[3] = {1, 2, 3}; const int l[3] = {4, 5, 6}; const int *p = r; //有效 p = l; //有效 p = &r[2]; //有效
只能把非const数据的地址赋值给普通指针。例如:
int r[3] = {1, 2, 3}; const int l[3] = {4, 5, 6}; int *p = r; //有效 p = l; //无效 p = &r[2]; //有效
鉴于以上规则,对函数的形参使用const不仅能保护数据,还能让函数处理const数组。反正,如果函数没有使用const形参,则不能将const数组名作为实参传递给该函数,因为,C标准规定,使用非const标识符修改const数据导致的结果是未定义的。
2、const指针。const还有一种用法是可以声明并初始化一个不能指向别处的指针,即const指针,注意const的位置:
int r[3] = {1, 2, 3}; int * const p = r; //指向数组的第一个元素 p = &r[2]; //不允许 *p = 5; //允许
const最后还有一种用法是在创建指针时同时使用两次,该指针既不能更改它所指向的地址,也不能修改指向地址上的值:
int r[3] = {1, 2, 3}; const int * const p = r; //指向数组的第一个元素 p = &r[2]; //不允许 *p = 5; //不允许
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6