本文使用執行環境如下:c/c++語言支援作業系統:ubuntu linux 18.04 64 bit
編譯環境:gcc version 7.5.0 (ubuntu 7.5.0-3ubuntu1~18.04)
const
關鍵字,const
意為「常數,不變的」,c++中可用於定義真正的常量,但在c語言中使用const
修飾的識別符號並不是真正意義上的常量,為唯讀變數,本文討論c語言const
關鍵字的常見用法。
}以上**段只在main
函式中定義了乙個長度為2的int
陣列,c規定陣列在編譯時必須確定長度,這裡顯式地用2
這個字面常量定義陣列長度,編譯執行是沒有問題的。
$ gcc const.c
$ ./a.out
如果使用const
修飾的變數定義陣列,編譯是否通過?
#include
intmain()
;return0;
}
編譯:
$ gcc const.c
const.c: in function 『main』:
const.c:7:5: error: variable-sized object may not be initialized
int arr[i]=;
^~~const.c:7:19: warning: excess elements in array initializer
int arr[i]=;
^const.c:7:19: note: (near initialization for 『arr』)
顯然,程式在編譯階段就停止了,const
修飾的識別符號i
在編譯階段無法確定其值,它不是個常量。
const.c
#include
intmain()
編譯執行:
$ gcc const.c
$ ./a.out
before, i = 2
after, i = 3
可以看到使用const
修飾的「常量」i
的值被改變了,如果此時想直接通過賦值修改i
的值
#include
intmain()
編譯:
$ gcc const
.cconst
.c: in function 『main』:
const
.c:15:7
: error: assignment of read-only variable 『i』
i =4;
^
編譯是不能通過的,編譯器提示這是個「唯讀變數」。
因此,c語言中使用const
關鍵字修飾的識別符號本質是唯讀變數,不能顯式給const
修飾的變數賦值,const
關鍵字修飾的識別符號並不是真正意義上的常量。
cosnt int a =1;
/* 等價於int const a = 1; */
常用的唯讀變數的定義方式,不希望a
被修改時新增const
修飾。
int a =1;
const
int*p =
&a;
從識別符號p
開始往左看,宣告中有*
號,則p
為指標;
識別符號p
旁邊沒有const
關鍵字,則指標的指向可以被改變(可以對p
賦值);
const
關鍵字貼近資料型別int
,則指標指向的資料不可變(不能對*p
賦值);
int a =1;
int*
const p =
&a;
從識別符號p
開始往左看,宣告中有*
號,則p
為指標;
const
關鍵字貼近識別符號p
,則指標的指向不可被改變(不能對p
賦值);
資料型別int
旁邊沒有const
關鍵字,則指標指向的資料可以被改變(可以對*p
賦值);
由於指標的指向不可被改變,p
在定義時必須完成初始化,後續再對p
賦值將編譯失敗。
int a =1;
const
int*
const p =
&a;
從識別符號p
開始往左看,宣告中有*
號,則p
為指標;
const
關鍵字貼近識別符號p
,則指標的指向不可被改變(不能對p
賦值);
const
關鍵字貼近資料型別int
,則指標指向的資料不可被改變(不能對*p
賦值);
由於指標的指向不可被改變,p
在定義時必須完成初始化,後續再對p
賦值將編譯失敗。
int a =1;
const
int*
const p =
&a;const
int*
const
*pp =
&p;
從識別符號pp
開始往左看,宣告中有*
號,則pp
為指標;
宣告中有兩個*
號,則pp
為指標的指標;
將const int * const *pp
分為兩部分:const int * const
和*pp
,可以發現pp
是const int * const
型別的指標,而const int * const
型別本身就是個指標型別,這個型別指標指向的資料不可被改變、指標的指向不可被改變;
const int * const
為「指向常量的常量指標」型別,則const int * const *
為「指向常量的常量指標的指標」型別;
pp
本身只是用於容納const int * const
型別的指標,因此pp
本身不必須在定義時完成初始化,後續可以對pp
賦值,pp
的值為const int * const
型別,因此不能對*pp
賦值,也不可對**pp
賦值。
void
*memcpy
(void
*dest,
const
void
*src, size_t n)
;
從src
識別符號往左看,宣告中有*
號,因此src
為指標;
src
識別符號旁沒有const
關鍵字,則指標的指向可以被改變(可以對src
賦值);
const
關鍵字貼近資料型別void *
,則指標指向的資料不可被改變(不能對*src
賦值);
從以上對memcpy
函式形參src
的分析中可知,使用const
關鍵字修飾形參指標,可以保護源資料在函式執行過程中不被意外修改,從而增強程式的健壯性。
本文首先從兩個方面論證了const
關鍵字在c語言中只能定義唯讀變數,接著分析了幾種c語言中常用的const
宣告,在適當的位置使用const
關鍵字能夠增強程式的健壯性。
C語言關鍵字 Const
c中const的使用 雖然這聽起來很簡單,但實際上,const的使用也是c語言中乙個比較微妙的地方,微妙在何處呢?請看下面幾個問題。問題 const變數 常量 為什麼下面的例子在使用乙個const變數來初始化陣列,ansi c的編譯器會報告乙個錯誤呢?const int n 5 int a n 答案...
C中const關鍵字
const 用法 定義常量,修飾指標 函式的輸入引數和返回值,把定義或者修飾的變數屬性設為唯讀。本質上它只是在全域性資料段或者棧中定義的是乙個唯讀的常量,不是真正位於字串常量區。所以關鍵字const 並不能把變數變成真正的常量,事實上還是可以改變 const 定義的變數的值。const 的目的是為了...
C語言關鍵字const
const 是constant的縮寫,只要有變數前面用const修飾,就意味著該變數裡面的資料是readonly。const可以修飾基本型別,構造型別,指標,等。const int a 10 去掉int a 的值不變 int const a 10 去掉int a的值不變 const int a 10...