用const來修飾變量
常量和變量的樣子完全一樣,只是常量的值不允許被修改。
例如:下面這兩種聲明方式所產生的效果是一樣的
const int a = 10;
int const a = 10;
用const來修飾指針
int const *p;
const int *p;
上面的兩個聲明方式產生的效果是一樣的,p都是一個指向整型常量的指針,因爲const修飾的是*p,所以我們不能修改p所指向的值,但是我們可以修改指針p的值。
int * const p;
上面的p是一個指向整形的常量指針,因爲const修飾的是p,所以我們可以修改p所指向的值*p,但是不能修改p的值。
int const * const p;
上面的聲明有兩個const,從左到右分別修飾了p所指向的值和p的值,所以我麼不能對這個表達式做任何修改。
注意:用const修飾變量時,一定要給其初始化,上面只是爲了舉例子所以沒有給初始化。
const與標識符
例如:
#define num 20
const int i = 20;
假如現在定義兩個數組arr[num]、arr[i],其中arr[num]是可以通過編譯的,而arr[i]是編譯不能通過的。
所以,在C語言裏面雖然const修飾的變量不能被修改,但它依然是一個變量,只不過具有了常量的屬性,所以可以稱爲常變量。
const在C語言中的總結:
1.將變量修飾限定爲常變量;
2.修飾函數的形參,保護形參不被修改;
3.可以修飾指針,所在位置不同修飾含義將會不同;
4.在另一個文件中引用常量extern const,可以保護被引用的值不被修改。
下面看一個例子,看看該程序最終的輸出結果:
const int num = 10;
int* ptr = (int *)#
*ptr = 20;
printf("%d\n",num);
程序輸出:10分析:因爲被const修飾的變量一般是不允許修改的,所以編譯器就會認爲被const修飾的變量就是一個常量,編譯器會優化將其放在寄存器中,每次都是從寄存器中取得這個值,所以當我們嘗試偷偷修改了內存中的值後,再讀取這個值,讀到的依然是沒修改之前的值,那是因爲我們讀取的時候會直接讀出寄存器裏的值,而我們當時修改的是內存中的值,爲了解決這個問題就需要加上volatile關鍵字,來保證內存的可見性。
volatile const int num = 10;
int* ptr = (int *)#
*ptr = 20;
printf("%d\n",num);
程序輸出:20
分析:此處添加volatile關鍵字,是爲了內存的可見性,讓每次取值都去內存中取,所以修改的就是內存中的值,打印出來的就是修改後的值。