const與指標

來源:互聯網
上載者:User

 C/C++中的關鍵字,CONST很濕讓人困惑的,所以總結了一下在網上看到的文章,留作筆記。(注意:C++與C中用略微不同)

 

Just like normal variables, pointers can be declared constant. There are two different ways that pointers and const can be intermixed, and they are very easy to mix up.

To declare a const pointer, use the const keyword between the asterisk and the pointer name:

12 int
nValue = 5;
int
*
const pnPtr = &nValue;

Just like a normal const variable, a const pointer must be initialized to a value upon declaration, and its value can not be changed. This means a const pointer will always point to the same value. In the above case, pnPtr will always point to the address
of nValue. However, because the value being pointed to is still non-const, it is possible to change the value being pointed to via dereferencing the pointer:

1 *pnPtr = 6;
// allowed, since pnPtr points to a non-const int

It is also possible to declare a pointer to a constant variable by using the const before the data type.

12 int
nValue = 5;
constint*pnPtr = &nValue;

Note that the pointer to a constant variable does not actually have to point to a constant variable! Instead, think of it this way: a pointer to a constant variable treats the variable as constant when it is accessed through the pointer.

Thus, the following is okay:

1 nValue = 6;
// nValue is non-const

But the following is not:

1 *pnPtr = 6;
// pnPtr treats its value as const

Because a pointer to a const value is a non-const pointer, the pointer can be redirected to point at other values:

12345 int
nValue = 5;
int
nValue2 = 6;
  constint*pnPtr = &nValue;pnPtr = &nValue2;
// okay

Confused? To summarize:

  • A non-const pointer can be redirected to point to other addresses.
  • A const pointer always points to the same address, and this address can not be changed.
  • A pointer to a non-const value can change the value it is pointing to.
  • A pointer to a const value treats the value as const (even if it is not), and thus can not change the value it is pointing to.

Finally, it is possible to declare a const pointer to a const value:

12 constintnValue;
constint*constpnPtr = &nValue;

A const pointer to a const value can not be redirected to point to another address, nor can the value it is pointing to be changed.

Const pointers are primarily used for passing variables to functions. We will discuss this further in the section on functions.

 

另外,來自百度百科的,寫的也很好。

 

const是一個C語言的關鍵字,它限定一個變數不允許被改變。使用const在一定程度上可以提高程式的安全性和可靠性,另外,在觀看別人代碼的時候,清晰理解const所起的作用,對理解對方的程式也有一些協助。另外CONST在其他程式設計語言中也有出現,如C++、PHP5、C#.net、HC08 C。

  C中CONST的使用:

  雖然這聽起來很簡單,但實際上,const的使用也是c語言中一個比較微妙的地方,微妙在何處呢?請看下面幾個問題。

  問題:const變數 & 常量

  為什麼下面的例子在使用一個const變數來初始化數組,ANSI C的編譯器會報告一個錯誤呢? 

  const int n = 5;

  int a[n];

  答案與分析:

  1)、這個問題討論的是“常量”與“唯讀變數”的區別。常量肯定是唯讀,例如5, "abc",等,肯定是唯讀,因為常量是被編譯器放在記憶體中的唯讀地區,當然也就不能夠去修改它。而“唯讀變數”則是在記憶體中開闢一個地方來存放它的值,只不過這個值由編譯器限定不允許被修改。C語言關鍵字const就是用來限定一個變數不允許被改變的修飾符(Qualifier)。上述代碼中變數n被修飾為唯讀變數,可惜再怎麼修飾也不是常量。而ANSI C規定數組定義時間長度度必須是“常量”,“唯讀變數”也是不可以的。

  2)、注意:在ANSI C中,這種寫法是錯誤的,因為數組的大小應該是個常量,而const int n,n只是一個變數(常量 != 不可變的變數,但在標準C++中,這樣定義的是一個常量,這種寫法是對的),實際上,根據編譯過程及記憶體配置來看,這種用法本來就應該是合理的,只是 ANSI C對數組的規定限制了它。

  3)、那麼,在ANSI C 語言中用什麼來定義常量呢?答案是enum類型和#define宏,這兩個都可以用來定義常量。

  問題:const變數 & const 限定的內容

  下面的代碼編譯器會報一個錯誤,請問,哪一個語句是錯誤的呢? 

  typedef char * pStr;

  char string[4] = "abc";

  const char *p1 = string;

  const pStr p2 = string;

  p1++;

  p2++;

  答案與分析:

  問題出在p2++上。

  1)、const使用的基本形式: const char m;

  限定m不可變。

  2)、替換1式中的m, const char *pm;

  限定*pm不可變,當然pm是可變的,因此問題中p1++是對的。

  3)、替換1式char, const newType m;

  限定m不可變,問題中的pStr就是一種新類型,因此問題中p2不可變,p2++是錯誤的。

  問題:const變數 & 字串常量

  請問下面的代碼有什麼問題?

  char *p = "i'm hungry!";

  p[0]= 'I';

  答案與分析:

  上面的代碼可能會造成記憶體的非法寫操作。分析如下, "i'm hungry"實質上是字串常量,而常量往往被編譯器放在唯讀記憶體區,不可寫。p初始指向這個唯讀記憶體區,而p[0] = 'I'則企圖去寫這個地方,編譯器當然不會答應。

  問題:const變數 & 字串常量2

  請問char a[3] = "abc" 合法嗎?使用它有什麼隱患?

  答案與分析:

  在標準C中這是合法的,但是它的生存環境非常狹小;它定義一個大小為3的數組,初始化為"abc",注意,它沒有通常的字串終止符'\0',因此這個數組只是看起來像C語言中的字串,實質上卻不是,因此所有對字串進行處理的函數,比如strcpy、printf等,都不能夠被使用在這個假字串上。

  問題5:const & 指標

  型別宣告中const用來修飾一個常量,有如下兩種寫法,那麼,請問,下面分別用const限定不可變的內容是什麼?

  1)、const在前面

  const int nValue; //nValue是const

  const char *pContent; //*pContent是const, pContent可變

  const (char *) pContent;//pContent是const,*pContent可變

  char* const pContent; //pContent是const,*pContent可變

  const char* const pContent; //pContent和*pContent都是const

  2)、const在後面,與上面的聲明對等

  int const nValue; // nValue是const

  char const * pContent;// *pContent是const, pContent可變

  (char *) const pContent;//pContent是const,*pContent可變

  char* const pContent;// pContent是const,*pContent可變

  char const* const pContent;// pContent和*pContent都是const

  答案與分析:

  const和指標一起使用是C語言中一個很常見的困惑之處,在實際開發中,特別是在看別人代碼的時候,常常會因為這樣而不好判斷作者的意圖,下面講一下我的判斷原則:

  當const所在程式碼片段中不包含括弧時,沿著*號劃一條線,如果const位於*的左側,則const就是用來修飾指標所指向的變數,即指標指向為常量;如果const位於*的右側,const就是修飾指標本身,即指標本身是常量。你可以根據這個規則來看上面聲明的實際意義,相信定會一目瞭然。

  另外,需要注意:對於const (char *) ; 因為char *是一個整體,相當於一個類型(如 char),因此,這時限定指標是const。

  一個簡單的判斷方法:指標運算子*,是從右至左,那麼如:char const * pContent,可以理解為char const (* pContent),即* pContent為const,而pContent則是可變的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.