亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

C語言 百文網(wǎng)手機(jī)站

C語言關(guān)鍵字const用法

時間:2022-03-18 14:46:50 C語言 我要投稿

C語言關(guān)鍵字const用法

  導(dǎo)語:C是高級語言,它把高級語言的基本結(jié)構(gòu)和語句與低級語言的實用性結(jié)合起來。下面就由小編為大家介紹一下C語言關(guān)鍵字const用法,歡迎大家閱讀!

  c語言中的const">C語言中的const

  const是C語言中保留的一個關(guān)鍵字,用來定義常量,如果一個變量被const修飾,那么它的值就不能被改變。使用符號常量寫出的代碼更容易維護(hù);一些指針常常是邊讀邊移動,而不是邊寫邊移動;許多編程規(guī)范對于函數(shù)參數(shù)會強(qiáng)制要求只讀不寫,在這些情況下,都需要借助const實現(xiàn)。

  那么有些人會問,C語言中不是已經(jīng)存在#define了嗎,為什么還要使用const呢?相比于#define,const修飾符有如下優(yōu)勢:

  1、 const能夠使編譯器進(jìn)行類型檢查,而預(yù)編譯指令#define只是簡單的對值進(jìn)行替換。

  2、 const可以保護(hù)被修飾的變量等,防止變量因為意外被修改,從而增強(qiáng)程序的健壯性。

  3、 編譯器通常不為普通const常量分配存儲空間,而是將他們保存在符號表中,這使得它成為了一個編譯期間的常量,沒有了存儲于內(nèi)存操作,使得它的效率很高。

  const用法

  const最常見的用法就是作為數(shù)組的邊界和switch分情況標(biāo)號,分類如下:

  常變量: const + 類型說明符 + 變量名

  常引用: const + 類型說明符 + &引用名

  常對象: 類名 + const 對象名

  常成員函數(shù): 類名::fun(形參) + const

  常數(shù)組: 類型說明符 + const 數(shù)組名[大小]

  常量指針: const + 類型說明符* 指針名 或者 類型說明符 + const *指針名

  首先提示的是:在常變量(const + 類型說明符 + 變量名)、常引用(const + 類型說明符 + &引用名)、常對象(類名 + const 對象名)、 常數(shù)組(類型說明符 + const 數(shù)組名[大小]), const”與“類型說明符”或“類名”(其實類名是一種自定義的類型說明符) 的位置可以互換。如:

1
2
const int a=5;
int const a=5; //等同

  其實這種可以很好理解,const只能修飾int(類型名或類名),所以二者是等同的。

  修飾局部變量

1
2
const int n=5;
int const n=5;

  這兩種寫法是一樣的,都是表示變量n的值不能被改變了,需要注意的是,用const修飾變量時,一定要給變量初始化(用來修飾函數(shù)的形參除外),否則之后就不能再進(jìn)行賦值了。C語言中,const定義的常量是全局的,C++中則是視聲明位置而定。

  接下來看看const用于修飾常量靜態(tài)字符串,例如:

1
const char* str = "fdsafdsa";

  如果沒有const的修飾,我們可能會在后面有意無意的寫str[4]=’x’這樣的語句,這樣會導(dǎo)致對只讀內(nèi)存區(qū)域的賦值,然后程序會立刻異常終止。有了const,這個錯誤就能在程序被編譯的時候就立即檢查出來,這就是const的好處。讓邏輯錯誤在編譯期被發(fā)現(xiàn)。

  常量指針與指針常量

  常量指針

  常量指針表示一個指向常量的指針,即該指針指向的內(nèi)容是個常量(至少該常量指針是這樣認(rèn)為的),可以有如下的定義方式:

1
2
const int * n;
int const * n;

  需要注意以下兩點:

  1。常量指針指向的值是不能改變的,但是這不意味指針本身不能改變,常量指針是可以指向其他的地址的。

1
2
3
4
5
int a=5;
int b=6;
const int* n = &a;
int const *n1 = &a;
n=&b;

  這個例子中,n和n1是等價的,都是指向a的一個常量指針,這時候有人會說,常量指針指向的應(yīng)該是一個常量吧,但是a并不是一個常量啊,為什么常量指針依舊可以指向a呢,這時候又要注意一下了:

  編譯器允許把非 const 對象的地址賦給指向 const 對象的指針,不允許把一個 const 對象的地址賦給一個普通的、非 const 對象的指針。

  其實這個也很好理解,對于一個變量,我可以對你增加束縛,用指向const對象的指針指向你,這只是意味著我現(xiàn)在認(rèn)為你是常量,不能通過這個常量指針對你進(jìn)行修改,但是對于第二種情況就不一樣了,你本來是一個被束縛的常量,如果用一個普通的指針指向你的話,就意味著我認(rèn)為你這個常量是一個變量,這樣或許我會在下面的代碼中,對你的值進(jìn)行修改,對一個const常量進(jìn)行修改,會發(fā)生什么,你應(yīng)該明白。

  然后回到上面的代碼,我們將a的地址給了n,然后在下一行又改變了n的值,將b的.地址賦給了n,這是沒有任何問題的,因為n只是一個指針,指向了一個常量,所以被稱為常量指針,它本身依舊是一個普通的指針,比較特殊的是它所指向的內(nèi)容,而不是它本身。所以它本身的值可以修改,指向不同的內(nèi)容。

  2。當(dāng)常量指針指向了一個變量時,不能通過這個常量指針改變變量的值,但是還是可以通過其他的引用來改變變量的值的。

1
2
3
4
5
6
int a=5;
const int* n=&a;
a=6; // 正確
*n = 7; //錯誤,對于常量指針,不能通過該指針來改變所指向的內(nèi)容(即使它所指向的內(nèi)容并不是一個常量)。
int *ni = (int *)n;
*n = 100; //正確

  在n這個指針眼中,n所指向的內(nèi)容是一個常量,所以不允許別人通過n本身對a進(jìn)行修改,但是a本質(zhì)上是一個變量,所以我們可以直接通過變量名或者新的普通指針對a進(jìn)行修改。實際上,在將程序載入內(nèi)存的時候,會有專門的一塊內(nèi)存區(qū)域來存放常量。但是,上面的a本身不是常量,是存放在棧或者堆中的。我們?nèi)匀豢梢孕薷乃闹怠6鴑不能修改指向的值應(yīng)該說是編譯器的一個限制。

  指針常量

  指針常量是指指針本身是一個常量,它只能指向一個固定的地址,不能指向別的地址。寫法如下:

1
int *const n;

  和上面的常量指針不一樣,指針常量是指指針本身比較特殊,而它所指的內(nèi)容并不特殊,因此,指針常量指向的內(nèi)容是可以修改的,可以通過別的指向該地址的指針進(jìn)行修改。如下所示:

1
2
3
4
int a=5;
int *p=&a;
int* const n=&a;
*p=8;

  在函數(shù)中,指針常量時表示不允許將該指針指向其他內(nèi)容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void func_02(int* const p)
{
int *pi = new int(100);
/* 錯誤!P是指針常量。不能對它賦值。 */
p = pi;
}
int main()
{
int* p = new int(10);
func_02(p);
p;
return 0;
}

  然后看下面的代碼:

1
2
const int *m1 = new int(10);
int* const m2 = new int(20);

  在上面的兩個表達(dá)式中,最容易讓人迷惑的是const到底是修飾指針還是指針指向的內(nèi)存區(qū)域?其實,只要知道:const只對它左邊的東西起作用,唯一的例外就是const本身就是最左邊的修飾符,那么它才會對右邊的東西起作用。根據(jù)這個規(guī)則來判斷,m1應(yīng)該是常量指針(即不能通過m1來修改它所指向的內(nèi)容。);而m2應(yīng)該是指針常量(即不能讓m2指向其他的內(nèi)存地址)。或者我們可以把星號看做指針,把const看做常量,那么m1就是常量指針,m2就是指針常量。

  指向常量的常指針

  是以上兩種的結(jié)合,指針指向的位置不能改變并且也不能通過這個指針改變變量的值,但是當(dāng)它指向一個變量時,依然可以通過其他的普通指針改變變量的值。

  const int* const p;

  修飾函數(shù)的參數(shù)

  根據(jù)常量指針與指針常量,const修飾函數(shù)的參數(shù)也是分為三種情況

  1。防止修改指針指向的內(nèi)容

1
void StringCopy(char *strDestination, const char *strSource);

  其中 strSource 是輸入?yún)?shù),strDestination 是輸出參數(shù)。給 strSource 加上 const 修飾后,如果函數(shù)體內(nèi)的語句試圖改動 strSource 的內(nèi)容,編譯器將指出錯誤。這種形式通常用于在數(shù)組形式的參數(shù)中模擬傳值調(diào)用。也就是相當(dāng)于函數(shù)調(diào)用者聲稱:”我給你一個指向它的指針,但你不能去修改它!比绻瘮(shù)編寫者遵循了這個約定,那么就相當(dāng)于模擬了值傳遞。這也是const最有用之處了:用來限定函數(shù)的形參,這樣該函數(shù)將不會修改實參指針?biāo)傅臄?shù)據(jù)。這里注意了,是函數(shù)不應(yīng)該去修改而不是不能修改,也就是說const不能阻止參數(shù)的修改(原因見上)。

  2。防止修改指針指向的地址

1
void swap (int* const p1 , int* const p2);

  指針p1和指針p2都是指針常量,指向的地址都不能修改。

  修飾函數(shù)的返回值

  很多時候,我們的函數(shù)中會返回一個地址或者引用。調(diào)用這得到這個返回的地址或者引用后就可以修改所指向或者代表的對象。這個時候如果我們不希望這個函數(shù)的調(diào)用這修改這個返回的內(nèi)容,就應(yīng)該返回一個常量。

  如果給以“指針傳遞”方式的函數(shù)返回值加 const 修飾,那么函數(shù)返回值(即指針)的內(nèi)容不能被修改,該返回值只能被賦給加const 修飾的同類型指針。

  例如函數(shù)

1
const char * GetString(void);

  如下語句將出現(xiàn)編譯錯誤:

1
char *str = GetString();

  正確的用法是

1
const char *str = GetString();

  修飾全局變量

  全局變量的作用域是整個文件,我們應(yīng)該盡量避免使用全局變量,以為一旦有一個函數(shù)改變了全局變量的值,它也會影響到其他引用這個變量的函數(shù),導(dǎo)致除了bug后很難發(fā)現(xiàn),如果一定要用全局變量,我們應(yīng)該盡量的使用const修飾符進(jìn)行修飾,這樣方式不必要的以為修改,使用的方法與局部變量是相同的。

  const 在c和c++中的區(qū)別

  C++中的const正常情況下是看成編譯期的常量,編譯器并不為const分配空間,只是在編譯的時候?qū)⑵谥当4嬖诿直碇?并在適當(dāng)?shù)臅r候折合在代碼中。所以,以下代碼:

  using namespace std;

  int main()

  {

  const int a = 1;

  const int b = 2;

  int array[ a + b ] = {0};

  for (int i = 0; i < sizeof array / sizeof *array; i++)

  {

  cout << array << endl;

  }

  }

  在可以通過編譯,并且正常運行。但稍加修改后,放在C編譯器中,便會出現(xiàn)錯誤:

  int main()

  {

  int i;

  const int a = 1;

  const int b = 2;

  int array[ a + b ] = {0};

  for (i = 0; i < sizeof array / sizeof *array; i++)

  {

  printf(“%d”,array);

  }

  }

  錯誤消息:

  c: est1 e。c(8): error C2057: 應(yīng)輸入常數(shù)表達(dá)式

  c: est1 e。c(8): error C2466: 不能分配常數(shù)大小為 0 的數(shù)組

  出現(xiàn)這種情況的原因是:在C中,const是一個不能被改變的普通變量,既然是變量,就要占用存儲空間,所以編譯器不知道編譯時的值。而且,數(shù)組定義時的下標(biāo)必須為常量。 在C語言中: const int size; 這個語句是正確的,因為它被C編譯器看作一個聲明,指明在別的地方分配存儲空間。但在C++中這樣寫是不正確的。C++中const默認(rèn)是內(nèi)部連接,如果想在C++中達(dá)到以上的效果,必須要用extern關(guān)鍵字。即C++中,const默認(rèn)使用內(nèi)部連接。而C中使用外部連接。

  (1) 內(nèi)連接:編譯器只對正被編譯的文件創(chuàng)建存儲空間,別的文件可以使用相同的表示符或全局變量。C/C++中內(nèi)連接使用static關(guān)鍵字指定。

  (2) 外連接:所有被編譯過的文件創(chuàng)建一片單獨存儲空間。一旦空間被創(chuàng)建,連接器必須解決對這片存儲空間的引用。全局變量和函數(shù)使用外部連接。通過extern關(guān)鍵字聲明,可以從其他文件訪問相應(yīng)的變量和函數(shù)。

【C語言關(guān)鍵字const用法】相關(guān)文章:

C語言關(guān)鍵字const的使用09-30

總結(jié)C語言中const關(guān)鍵字的使用10-01

c++中const關(guān)鍵字09-23

C語言中const關(guān)鍵字的使用方法10-05

C語言中Static和Const關(guān)鍵字的作用09-26

assert用法(C語言)11-24

32個C語言關(guān)鍵字10-07

C語言關(guān)鍵字RESTRICT介紹09-22

C語言指針的用法10-05

c語言new的用法10-04