情景分析“C語言的const關鍵字”

來源:互聯網
上載者:User
C語言中的const一直是C語言初學者心中的痛,這是因為const在不同位置有不同作用,在不同情景有不同角色。這讓初學者摸不清頭腦。今天,和大家一起研究一下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有其劣勢,請參閱:http://dongpingli.blogspot.com/2009/02/define.html
:)
==============================================================================================

情景三: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了!

================================================================================
除了傳遞要求為const的參數以外,自己聲明對象沒有什麼必須要加,但是對於一個邏輯上不應該被修改,應該為常量的對象,沒有聲明為const,就必須由程式員自己來維護,來記住這個變數不應該被修改,即使你不小心修改導致程式整體混亂了,編譯器也不會報錯
另,const和普通變數的聲明存在於標頭檔時有區別,總之這些都是與你具體寫程式的規劃有關係,const這個玩意只是方便程式設計和程式編寫,能夠使程式更加的清晰,如果說我就是不愛用,就是喜歡一路變數用到底,那也沒什麼不行。。。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.