1. const限定符和指针
(1)const限定符通知编译器禁止修改某个特定的变量。
(2)用const作为函数参数有六种可能性,两种用于传值调用,四种用于传引用调用。并用最低访问权原则指导我们选择某种调用方式。
(3)如果传递给函数的值没有(或不应该)在函数体中被修改,应该用const声明该值以防被意外修改
(4)给函数传递的指针有如下四种情况,每种情况都有不同级别的访问权:
1)指向非常量数据的非常量指针:具有最高访问权。允许通过指针复引用来修改数据并能够通过修改指针使它指向其它数据项。把非常量指针传给非常量数据不包含关键字const。这种指针可能会用来接收一个字符串参数,函数然后用指针算法处理(可能是修改)字符串中的每一个字符。例子说明如下,该函数将一个小写的字符串转换成大写的字符串。
void convertToUppercase( char * );
main( void )
{
char string [] = " characters " ;
printf( " before conversion: %s /n " , string );
convertToUppercase( string );
printf( " after conversion: %s /n " , string );
return 0 ;
}
void convertToUppercase( char * s)
{
while ( * s != ' /0 ' )
{
if ( * s >= ' a ' && * s <= ' z ' )
* s -= 32 ; // 把小写转换成大写
++ s; // 地址加1指向下一个字符
}
}
2)指向常量数据的非常量指针:可以修改指向常量数据的非常量指针使它指向具有合适类型的任何数据项,但是它所指向的数据项是不能被修改的。这种指针可能会用来接收一个数组参数,然后让函数在不修改数据的情况下处理数组的每一个元素。以下是一个字符串输出函数,实例如下:
void printCharacters( const char * );
main( void )
{
char string [] = " print characters of a string " ;
printf( " The string is: " );
printCharacters( string );
putchar( ' /n ' );
return 0 ;
}
void printCharacters( const char * s)
{
for (; * s != ' /0 ' ; s ++ )
putchar( * s);
}
3)指向常量数据的常量指针:具有最少访问权。这种指针总是指向同一个内存单元,并且该内存单元中的数据不能被修改。以下程序声明了一个const int * const类型的指针变量ptr(读法:ptr是一个指向整型常量的常量指针)。程序试图修改ptr所指向的数据和指针变量中存储的地址,结果产生了编译错误。
main( void )
{
int x = 5 , y;
const int * const ptr =& x;
* ptr = 7 ; // error C2166: l-value specifies const object
ptr =& y; // error C2166: l-value specifies const object
return 0 ;
}
4)指向非常量数据的常量指针:指向非常量数据的常量指针总是指向一个内存单元,其中的数据可通过该指针修改。数组名就是这种情况。数组名是一个指向数组起始地址的常量指针,可以用数组名和数组下标访问数组中的所有的数据。指向非常量数据的常量指针可用作接收一个数组的函数参数,函数只用数组下标就可以访问数组元素。
声明为const的指针必须在声明时初始化(如果它是函数的参数,用传递给函数的指针初始化)。以下程序试图修改一个常量指针。指针ptr声明为int * const类型(读法:指针ptr是一个指向某整数的常量指针),它用整数变量x的地址初始化。程序试图把y的地址赋值给ptr,因而编译器报错。
main( void )
{
int x, y;
int * const ptr =& x;
ptr =& y; // error C2166: l-value specifies const object
return 0 ;
}
(5)在调用以数组作为参数的函数时,该数组是自动以传引用方式传递给函数的,但是结构总是以传值方式传递的(即传递整个结构的一个拷贝)。对每一个结构做一份拷贝以及把它存储在堆栈中需要一些开销。在必须给函数传递结构时,我们可以传递指向常量数据的指针,这样既能获得传引用调用的性能又能象传值调用那样保护数据。传递指向结构的指针只需要拷贝一份存储结构的地址。