C之我見 const關鍵字

2021-10-25 02:03:55 字數 4768 閱讀 1589

本文使用執行環境如下:

作業系統:ubuntu linux 18.04 64 bit

編譯環境:gcc version 7.5.0 (ubuntu 7.5.0-3ubuntu1~18.04)

c/c++語言支援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,可以發現ppconst 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...