const int a = 1; int const a = 1;
const關鍵字修飾變量a,表示a是一個整型變量,且這個變量的值是不可改變的。這兩個定義的做用同樣,編譯後變量a分配在只讀數據段中,這個數據段在一塊只讀的內存區域中,任何對這塊區域的操做都是非法的。函數
以下面的程序:spa
#include <stdio.h> int main(void) { int const a = 100; a = 200; return 0; }
編譯器會報錯:指針
因此在定義的時候對該變量溫馨化是使得該變量具備值的惟一機會。調試
const關鍵字在指針變量的定義以前,以下所示:code
int const a = 100; const int *p; //指針指向的內容不能改變 //等同於 int const *p; p = &a;
該定義表示p是一個指針變量,指向一個整型變量的存儲空間,而且這個整型變量是一個不可改變的值的變量。也就是說指針p是能夠改變的,而指針所指向的內容是不可改變的。內存
例如:開發
#include <stdio.h> int main(void) { int a = 100; int b = 200; const int *p; p = &a; printf("a = %d\n", *p); *p = 200; //錯誤,指針所指向的內容(經過*p方式)不能改變 p = &b; //正確,指針自己能夠改變 printf("a = %d\n", *p); return 0; }
運行結果爲:字符串
const關鍵字在指針變量的定義之中:編譯器
int a = 100; int * const p = &a; //指針自己不能改變
該定義表示p是一個指針變量,指向一個整型變量的存儲空間,而且這個整型變量是一個能夠改變值的變量。而指針p的值不能改變,只能永遠指向這個內存單元,也就是說指針p是不能夠改變的,而指向的內容是能夠改變的。string
例如:
#include <stdio.h> int main(void) { int a = 100; int b = 200; int * const p = &a; printf("a = %d\n", *p); *p = 200; //正確,指針所指向的內容(經過*p方式)能夠改變 //p = &b; //指針自己不能夠改變 printf("a = %d\n", *p); return 0; }
運行結果:
在指針變量定義以前和定義之中均有關鍵字,以下:
const int a = 100; int const * const p = &a; //指針和指針指向的內容都不能改變
該定義表示a是一個指針變量,指向一個整型變量的存儲空間。這個整型變量是一個不能改變值的變量,並且指針a的值也不能改變:
例如:
#include <stdio.h> int main(void) { int a = 100; int b = 200; int const * const p = &a; printf("a = %d\n", *p); *p = 200; //錯誤,指針所指向的內容不能改變 p = &b; //錯誤,指針自己不能夠改變 printf("a = %d\n", *p); return 0; }
編譯結果:
指向非const變量的指針或者非const變量的地址能夠傳給指向const變量的指針,C語言能夠作隱式轉換,以下:
int a = 100; const int *p; p = &a; //常量指針指向一個普通變量
可是指向const變量的指針,或者const變量的指針幣能夠傳給非const變量的指針,以避免意外修改了const存儲區的內容,以下:
const int a = 100; int *p = &a; //普通指針不能指向一個常量變量
第一點是最重要的,來看一個程序:
#include <stdio.h> //將全部空格替換爲"_",失敗返回NULL char * replace(char *str) { char *p; if(str == NULL) return NULL; p = str; while(*p != '\0'){ if(*p == ' ') *p = '_'; //進行字符串的替換 p++; } return p; } int main(void) { char *p = "hello world and china\n"; if(replace(p) != NULL) printf("the string : %s\n", p); return 0; }
編譯並運行程序:
程序出現了段錯誤,說明內存訪問出錯了,這個錯誤出如今*p = '_';這個語句上。該語句將字符串的值修改,可是做爲replace()函數的參數的源字符串是一個字符串常量,這個常量被分配在只讀數據段中。所以對次字符串的操做形成了非法內存訪問,出現了段錯誤。
若是使用const關鍵字能夠很好的預防這個問題。
修改上面的程序,使用const關鍵字對字符創常量進行聲明,編譯器會發現修改常量的錯誤:
#include <stdio.h> //將全部空格替換爲"_",失敗返回NULL const char * replace(const char *str) //使用const修飾變量 { const char *p; if(str == NULL) return NULL; p = str; while(*p != '\0'){ if(*p == ' ') *p = '_'; //進行字符串的替換 p++; } return p; } int main(void) { const char *p = "hello world and china\n"; //將源字符串聲明爲const變量 if(replace(p) != NULL) printf("the string : %s\n", p); return 0; }
編譯結果:
編譯器報錯,提示*p = '_';出錯,程序試圖寫只讀數據段的錯誤被編譯器發現了,這時開發人員能夠很容易就能夠發現這個錯誤。原本在運行時纔出現的錯誤,在編譯階段就由編譯器發現了,這樣就省了大量的調試時間,這對程序開發來講是頗有益的。