C語言的const關鍵字

簡單方法:
 
 int const nValue; // nValue是const
  char const * pContent;// *pContent是const, pContent可變
  (char *) const pContent;//pContent是const,*pContent可變
  char* const pContent;// pContent是const,*pContent可變
  char const* const pContent;// pContent和*pContent都是const
  答案與分析:
  const和指針一起使用是C語言中一個很常見的困惑之處,在實際開發中,特別是在看別人代碼的時候,常常會因爲這樣而不好判斷作者的意圖,下面講一下我的判斷原則:
  沿着*號劃一條線,const和誰在一邊,那麼誰就是const,即const限定的元素就是它。你可以根據這個規則來看上面聲明的實際意義,相信定會一目瞭然。
  另外,需要注意:對於const (char *) ; 因爲char *是一個整體,相當於一個類型(如 char),因此,這是限定指針是const。
 
情景一:最簡單的const用法
#include<stdio.h>
int main()
{
int const a;
a=5;
printf("a=%d\n",a);
return 0;
}
如果編譯這個c文件,就會報錯:
1071.c: In function ‘main’:
1071.c:5: error: assignment of read-only variable ‘a’
顯而易見,這是const在搞鬼,因爲聲明瞭const的變量是不能修改的!
如果將源代碼修改爲如下這樣,就沒有問題了!
#include<stdio.h>
int main()
{
int const a=5;
printf("a=%d\n",a);
return 0;
}
總結:const聲明的變量必須要進行初始化賦值,如果錯過這個機會,以後再想給const的變量賦值,可就沒門了!切記~
PS:int const和const int是一回事,“顛倒寫”都是可以的。以後遇到了別犯暈,呵呵。但是,還是要留個心眼,當const和指針攙和到一起時,這個“顛倒寫”的規律可未必成立。
==============================================================================================
情景二:發明const爲了什麼?
在const誕生之前,開發者一直使用#define VAR 100來定義一些有特殊用途的類常量,不過這樣定義是存在一些劣勢的。因此const應運而生,之後開發者可以使用const int VAR=100;來定義類常量了。
至於爲什麼#define有其劣勢,還要讀者自己去google下。:)
==============================================================================================
情景三:const和指針的配合是噩夢!
你能分辨得清這些聲明麼:
const int *A;
int const *A;
int *const A;
const int *const A;
如果有點犯暈的話,那就先給出它們的講解,然後繼續看後面的情景分析吧。
const int *A; //修飾指向的對象,A可變,A指向的對象不可變
int const *A;   //修飾指向的對象,A可變,A指向的對象不可變
int *const A;   //修飾指針A, A不可變,A指向的對象可變
const int *const A; //指針A和A指向的對象都不可變
==============================================================================================
情景四:const int *A
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
const int *A=&num;
printf("result=%d\n",*A);
return 0;
}
編譯執行結果爲:
[rocrocket@wupengchong const_test]$ cc test1.c
[rocrocket@wupengchong const_test]$ ./a.out
result=12
接下來,我們動動手腳,在代碼中加入了(*A)++;這條語句:
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
const int *A=&num;
(*A)++;
printf("result=%d\n",*A);
return 0;
}
編譯這個c文件:
[rocrocket@wupengchong const_test]$ !cc
cc test1.c
test1.c: In function ‘main’:
test1.c:6: error: increment of read-only location ‘*A’
可以看到,報錯了,報錯的內容表示”*A”是隻讀的,不能修改。
我們再修改一下源代碼爲下面這樣:
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
int tmp=100;
const int *A=&num;
A=&tmp;
printf("result=%d\n",*A);
return 0;
}
編譯執行結果爲:
[rocrocket@wupengchong const_test]$ !cc
cc test1.c
[rocrocket@wupengchong const_test]$ ./a.out
result=100
好了,如果你仔細看了這幾個小得不能再小的程序,你自己都可以給出結論了!
結論:如果聲明瞭const int *A,那麼A值是可以修改的,而*A是不可以修改的。更通俗的說,A指針可以隨便指向一個整型,但只要被A盯上了的整型變量在使用*A引用時就不能修改了。
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
int tmp=100;
const int *A=&num;
A=&tmp;
tmp=3;
printf("result=%d\n",*A);
return 0;
}
編譯執行的結果爲:
[rocrocket@wupengchong const_test]$ !cc
cc test1.c
[rocrocket@wupengchong const_test]$ ./a.out
result=3
結論2:即使A指向了tmp,我雖然不能修改*A,但是我仍然是可以用tmp來修改這個值的,完全不管*A的存在。呵呵
==============================================================================================
情景五:int *const A
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
int *const A=&num;
printf("result=%d\n",*A);
return 0;
}
編譯執行結果爲:
[rocrocket@wupengchong const_test]$ !cc
cc test1.c
[rocrocket@wupengchong const_test]$ ./a.out
result=12
我們稍微修改下源代碼:
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
int tmp=100;
int *const A=&num;
A=&tmp;
printf("result=%d\n",*A);
return 0;
}
編譯時報錯了:
[rocrocket@wupengchong const_test]$ !cc
cc test1.c
test1.c: In function ‘main’:
test1.c:7: error: assignment of read-only variable ‘A’
[rocrocket@wupengchong const_test]$ cat test1.c
可見A本身的值已經不能再變了。
繼續修改源代碼如下:
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
int *const A=&num;
(*A)=100;
printf("result=%d\n",*A);
return 0;
}
編譯執行結果爲:
[rocrocket@wupengchong const_test]$ !cc
cc test1.c
[rocrocket@wupengchong const_test]$ ./a.out
result=100
可以看出,(*A)是可以改變的。
結論又可以輕易推出了:int *const A;   //const修飾指針A, A不可變,A指向的對象可變
==============================================================================================
情景六:const int *const A; //指針A和A指向的對象都不可變
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
int const *const A=&num;
(*A)=100;
printf("result=%d\n",*A);
return 0;
}
編譯會報錯:
[rocrocket@wupengchong const_test]$ !cc
cc test1.c
test1.c: In function ‘main’:
test1.c:6: error: assignment of read-only location ‘*A’
改下源代碼:
[rocrocket@wupengchong const_test]$ cat test1.c
#include<stdio.h>
int main()
{
int num=12;
int tmp=100;
int const *const A=&num;
A=&tmp;
printf("result=%d\n",*A);
return 0;
}
編譯仍然會報錯:
[rocrocket@wupengchong const_test]$ !cc
cc test1.c
test1.c: In function ‘main’:
test1.c:7: error: assignment of read-only variable ‘A’
呵呵,結論很明顯了,const int *const A; //指針A和A指向的對象都不可變
當然const int *const A;和int const *const A=&num;是等價的!
情景七:如果const用在函數形參裏呢?是不是又要複雜很多?
答案是NO!一點也不復雜。
來看看這個函數投:int addnum(const int num, int a, int b);
這個函數聲明中的第一個形參是const int num,這就表明如果我調用了這個函數,那麼第一個實參被傳到addnum函數裏之後,就不能再做修改了!呵呵 就這麼簡單。
給個例子吧,讓大家能更一目瞭然:
[rocrocket@wupengchong const_test]$ cat test2.c
#include<stdio.h>
int addto(const int num, int a, int b)
{
if(num==1){
return a+b;
}else{
return 0;
}
}
 
int main(){
int num=100;
int a=12,b=22;
int res;
num=1;
res=addto(num,a,b);
printf("res=%d\n",res);
return 0;
}
編譯執行結果爲:
[rocrocket@wupengchong const_test]$ !cc
cc test2.c
[rocrocket@wupengchong const_test]$ ./a.out
res=34
如果我修改一下,編譯就會出錯:
[rocrocket@wupengchong const_test]$ cat test2.c
#include<stdio.h>
int addto(const int num, int a, int b)
{
if(num==1){
num=3;
return a+b;
}else{
return 0;
}
}
 
int main(){
int num=100;
int a=12,b=22;
int res;
num=1;
res=addto(num,a,b);
printf("res=%d\n",res);
return 0;
}
編譯報錯爲:
[rocrocket@wupengchong const_test]$ !cc
cc test2.c
test2.c: In function ‘addto’:
test2.c:5: error: assignment of read-only location ‘num’
可見在函數裏形參被聲明爲const的變量也是不能修改的哦!呵呵~
const其實不難,把本文的幾個小例子看懂就OK了!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章