在函數調用時,我們經常看見一個函數的接受參數為(const char *);
例如strlen()函數,它的定義為:
size_t strlen( const char *str);
那么將形參設置為const的到底有什么好處呢?網絡上經常的回答是:這樣將把形參限定為常量,使得我們不能修改它。總感覺這種說法似乎是明白了,但再仔細的想下,總覺得少點什么。
在我看來,這樣做的好處有2點:
第一, 保證了實參不能被修改,增加了安全性。
第二, 擴大了該函數的參數的接收范圍,使得函數更具通用性。
而第二點,在我看來,是讓我恍然大悟的,終於理解了const的作用。
從下邊這個例子中,我們可以看出這兩點好處;寫一個函數length(),實現與strlen()相同的功能,然后進行調用,代碼如下:
#include <string>
#include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;
void length(char *s)
{
int count = 0;
for (;*s++ !='/0';count++);
printf("common length: %d/n",count);
}
int _tmain(int argc, _TCHAR* argv[])
{
char str1[] = "you are a boy 1!";
length(str1); //字符數組
length("you are a boy2 !"); //常量
char *s = "you are a boy 3!";
length(s); //字符指針
return 0;
}
上面程序可以正確的編譯運行,並且輸出3行“common length:16”。
但是,如果我想計算一下一個string類型的長度呢?因為length(char *s)的接受參數為char *,我們可以使用stirng類的c_str()方法返回string的字符指針(char *),於是,我們這樣操作:
string str2 = "you are a boy 5!";length(str2.c_str());
上邊的做法看起來沒什么錯誤,可是這樣是通不過編譯的,因為str2.c_str()返回的是const char *,而我們的length接受的是char *,const char * 是不能轉換成 char *的。
因為const char * s 表示其指針所指向的內容是只讀的,不能被修改,而char * s指向的內容是可以修改的,把一個常量指針轉換成普通的指針,這顯然是不符合邏輯的。關於常量指針和指針常量以及普通的指針的區別,請查閱相關文檔。
我們再回過頭來看length的需求,length的目的是計算出字符串的長度,它不對字符串本身做修改,對於類似的這種需求的函數(不修改實參),我們應該而且強烈推薦使用const來修飾形參,這也是一種良好的編碼習慣。
很明顯的看出,如果這樣定義:void length(char *s),它將不能接受常量字符指針與常量字符數組。這正是使用const定義形參的第2個好處:擴大了該函數的參數的接收范圍;使得函數更具通用性。
常量字符指針是指:str2.c_str()或者str2.data()的返回值,或者自己定義的
常量字符數組是指:const char str1[] = "you are a boy 1!";