程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> 情景分析“C語言的const關鍵字”

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

編輯:關於C

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有其劣勢,還要讀者自己去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的存在。呵呵www.2cto.com

==============================================================================================

情景五: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這個玩意只是方便程序設計和程序編寫,能夠使程序更加的清晰,如果說我就是不愛用,就是喜歡一路變量用到底,那也沒什麼不行
 


摘自 C'est la vie 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved