国产成人v爽在线免播放观看,日韩欧美色,久久99国产精品久久99软件,亚洲综合色网站,国产欧美日韩中文久久,色99在线,亚洲伦理一区二区

學(xué)習(xí)啦 > 學(xué)習(xí)英語 > 專業(yè)英語 > 計算機(jī)英語 > c語言const的用法

c語言const的用法

時間: 長思709 分享

c語言const的用法

  const是一個C語言的關(guān)鍵字,它限定一個變量不允許被改變。使用const在一定程度上可以提高程序的安全性和可靠性,另外,在觀看別人代碼的時候,清晰理解const所起的作用,對理解對方的程序也有一些幫助。下面小編就跟大家介紹下c語言const的用法。

  我們來分情況看語法上它該如何被使用。

  1、函數(shù)體內(nèi)修飾局部變量。

  例:

  void func()

  {

  const int a=0;

  }

  首先,我們先把const這個單詞忽略不看,那么a是一個int類型的局部自動變量,我們給它賦予初始值0。然后再看const.

  const作為一個類型限定詞,和int有相同的地位。

  const int a;

  int const a;

  是等價的。于是此處我們一定要清晰的明白,const修飾的對象是誰,是a,和int沒有關(guān)系。const 要求他所修飾的對象為常量,不可被改變,不可被賦值,不可作為左值(l-value)。

  這樣的寫法也是錯誤的。

  const int a;

  a=0;

  這是一個很常見的使用方式:

  const double pi=3.14;

  在程序的后面如果企圖對pi再次賦值或者修改就會出錯。

  然后看一個稍微復(fù)雜的例子。

  const int* p;

  還是先去掉const 修飾符號。

  注意,下面兩個是等價的。

  int* p;

  int *p;

  其實我們想要說的是,*p是int類型。那么顯然,p就是指向int的指針。

  同理

  const int* p;

  其實等價于

  const int (*p);

  int const (*p);

  即,*p是常量。也就是說,p指向的數(shù)據(jù)是常量。

  于是

  p+=8; //合法

  *p=3; //非法,p指向的數(shù)據(jù)是常量。

  那么如何聲明一個自身是常量指針呢?方法是讓const盡可能的靠近p;

  int* const p;

  const右面只有p,顯然,它修飾的是p,說明p不可被更改。然后把const去掉,可以看出p是一個指向 int形式變量的指針。

  于是

  p+=8; //非法

  *p=3; //合法

  再看一個更復(fù)雜的例子,它是上面二者的綜合

  const int* const p;

  說明p自己是常量,且p指向的變量也是常量。

  于是

  p+=8; //非法

  *p=3; //非法

  const 還有一個作用就是用于修飾常量靜態(tài)字符串。

  例如:

  const char* name="David";

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

  const 還可以用來修飾數(shù)組

  const char s[]="David";

  與上面有類似的作用。

  2、在函數(shù)聲明時修飾參數(shù)

  來看實際中的一個例子。

  NAME

  memmove -- copy byte string

  LIBRARY

  Standard C Library (libc, -lc)

  SYNOPSIS

  #include <string.h>

  void *

  memmove(void *dst, const void *src, size_t len);

  這是標(biāo)準(zhǔn)庫中的一個函數(shù),用于按字節(jié)方式復(fù)制字符串(內(nèi)存)。它的第一個參數(shù),是將字符串復(fù)制到哪里去(dest),是目的地,這段內(nèi)存區(qū)域必須是可寫。它的第二個參數(shù),是要將什么樣的字符串復(fù)制出去,我們對這段內(nèi)存區(qū)域只做讀取,不寫。于是,我們站在這個函數(shù)自己的角度來看,src 這個指針,它所指向的內(nèi)存內(nèi)所存

  儲的數(shù)據(jù)在整個函數(shù)執(zhí)行的過程中是不變。于是src所指向的內(nèi)容是常量。于是就需要用const修飾。例如,我們這里這樣使用它。

  const char* s="hello";

  char buf[100];

  memmove(buf,s,6); //這里其實應(yīng)該用strcpy或memcpy更好

  如果我們反過來寫,

  memmove(s,buf,6);

  那么編譯器一定會報錯。事實是我們經(jīng)常會把各種函數(shù)的參數(shù)順序?qū)懛?。事實是編譯器在此時幫了我們大忙。如果編譯器靜悄悄的不報錯,(在函數(shù)聲明處去掉const即可),那么這個程序在運(yùn)行的時候一定會崩潰。

  這里還要說明的一點是在函數(shù)參數(shù)聲明中const一般用來聲明指針而不是變量本身。

  例如,上面的size_t len,在函數(shù)實現(xiàn)的時候可以完全不用更改len的值,那么是否應(yīng)該把len也聲明為常量呢?可以,可以這么做。我們來分析這么做有什么優(yōu)劣。

  如果加了const,那么對于這個函數(shù)的實現(xiàn)者,可以防止他在實現(xiàn)這個函數(shù)的時候修改不需要修改的值(len),這樣很好。

  但是對于這個函數(shù)的使用者,

  1。這個修飾符號毫無意義,我們可以傳遞一個常量整數(shù)或者一個非常量整數(shù)過去,反正對方獲得的只是我們傳遞的一個copy。

  2。暴露了實現(xiàn)。我不需要知道你在實現(xiàn)這個函數(shù)的時候是否修改過len的值。

  所以,const一般只用來修飾指針。

  再看一個復(fù)雜的例子

  int execv(const char *path, char *const argv[]);

  著重看后面這個,argv.它代表什么。

  如果去掉const,我們可以看出

  char * argv[];

  argv是一個數(shù)組,它的每個元素都是char *類型的指針。

  如果加上const.那么const修飾的是誰呢?他修飾的是一個數(shù)組,argv[],意思就是說這個數(shù)組的元素是只讀的。那么數(shù)組的元素的是什么類型呢?是char *類型的指針.也就是說指針是常量,而它指向的數(shù)據(jù)不是。

  于是

  argv[1]=NULL; //非法

  argv[0][0]='a'; //合法

  3、全局變量。

  我們的原則依然是,盡可能少的使用全局變量。我們的第二條規(guī)則 則是,盡可能多的使用const。如果一個全局變量只在本文件中使用,那么用法和前面所說的函數(shù)局部變量沒有什么區(qū)別。如果它要在多個文件間共享,那么就牽扯到一個存儲類型的問題。

  有兩種方式。

  1.使用extern

  例如

  extern const double pi;

  const double pi=3.14;

  然后其他需要使用pi這個變量的,包含file1.h

  #include "file1.h"

  或者,自己把那句聲明復(fù)制一遍就好。

  這樣做的結(jié)果是,整個程序鏈接完后,所有需要使用pi這個變量的共享一個存儲區(qū)域。

  2.使用static,靜態(tài)外部存儲類

  static const pi=3.14;

  需要使用這個變量的*.c文件中,必須包含這個頭文件。

  前面的static一定不能少。否則鏈接的時候會報告說該變量被多次定義。這樣做的結(jié)果是,每個包含了constant.h的*.c文件,都有一份該變量自己的copy,該變量實際上還是被定義了多次,占用了多個存儲空間,不過在加了static關(guān)鍵字后,解決了文件間重定義的沖突。壞處是浪費(fèi)了存儲空間,導(dǎo)致鏈接完后的可執(zhí)行文件變大。但是通常,這個,小小幾字節(jié)的變化,不是問題。好處是,你不用關(guān)心這個變量是在哪個文件中被初始化的。

  最后,說說const的作用。

  const 的好處,是引入了常量的概念,讓我們不要去修改不該修改的內(nèi)存。直接的作用就是讓更多的邏輯錯誤在編譯期被發(fā)現(xiàn)。所以我們要盡可能的多使用const。但是很多人并不習(xí)慣使用它,更有甚者,是在整個程序 編寫/調(diào)試 完后才補(bǔ)const。如果是給函數(shù)的聲明補(bǔ)const,尚好。如果是給 全局/局部變量補(bǔ)const,那么……那么,為時已晚,無非是讓代碼看起來更漂亮了。

512460