1. 程式人生 > >理解常量指針與指針常量?

理解常量指針與指針常量?

erro 聲明 c語言 .cn strong 傳遞 通過 () 指針常量

constant

*前面的是對被指向對象的修飾,*後面的是對指針本身的修飾

常量指針(被指向的對象是常量)

定義:

又叫常指針,可以理解為常量的指針,指向的是個常量

關鍵點:

  1. 常量指針指向的對象不能通過這個指針來修改,可是仍然可以通過原來的聲明修改;
  2. 常量指針可以被賦值為變量的地址,之所以叫常量指針,是限制了通過這個指針修改變量的值;
  3. 指針還可以指向別處,因為指針本身只是個變量,可以指向任意地址; 

代碼形式:

int const* p;  const int* p;
//
// Created by zhangrongxiang on 2018/3/25 22:16
// File constant4
// #include <stdio.h> // 常量指針(被指向的對象是常量) int main() { int i = 10; int i2 = 11; const int *p = &i; printf("%d\n", *p);//10 i = 9; //OK,仍然可以通過原來的聲明修改值, //Error,*p是const int的,不可修改,即常量指針不可修改其指向地址 //*p = 11; //error: assignment of read-only location ‘*p’ p = &i2;//OK,指針還可以指向別處,因為指針只是個變量,可以隨意指向;
printf("%d\n", *p);//11 return 0; }

指針常量(指針本身是常量)

定義:

本質是一個常量,而用指針修飾它。指針常量的值是指針,這個值因為是常量,所以不能被賦值。

關鍵點:

  1. 它是個常量!
  2. 指針所保存的地址可以改變,然而指針所指向的值卻不可以改變;
  3. 指針本身是常量,指向的地址不可以變化,但是指向的地址所對應的內容可以變化;

代碼形式:

int* const p;
//
// Created by zhangrongxiang on 2018/3/25 22:30
// File constan5
//
//指針常量(指針本身是常量)
#include <stdio.h>
int main() { int i = 10; int *const p = &i; printf("%d\n", *p);//10 //Error,因為p是const 指針,因此不能改變p指向的內容 //p++;//error: increment of read-only variable ‘p’ (*p)++; //OK,指針是常量,指向的地址不可以變化,但是指向的地址所對應的內容可以變化 printf("%d\n", *p);//11 i = 9;//OK,仍然可以通過原來的聲明修改值, return 0; }

指向常量的常指針

定義:

指向常量的指針常量就是一個常量,且它指向的對象也是一個常量。

關鍵點:

  1. 一個指針常量,指向的是一個指針對象;
  2. 它指向的指針對象且是一個常量,即它指向的對象不能變化;

代碼形式:

const int* const p;
//
// Created by zhangrongxiang on 2018/3/25 22:38
// File constant6
//
#include <stdio.h>

int main() {
    int i = 10;
    const int *const p = &i;
    printf("%d\n", *p);//10
    //p++;//error: increment of read-only variable ‘p’
    //(*p)++;//increment of read-only location ‘*p’
    i++;//OK,仍然可以通過原來的聲明修改值
    printf("%d\n", *p);//11
    return 0;
}

const int a / int const a

如果我們給出 const int a;你應該知道這是將a常量化了,但是為什麽那?那是因為intconst都作為一個類型限定詞,有相同的地位。所以你也可以寫成 int const a;似乎這樣更加好理解!當然這都不難,難點在哪裏哪?當然此時你如果定義指針也是可以修改的,但是會報警告!當然強制類型轉換後警告也不會報了!

//
// Created by zhangrongxiang on 2018/3/25 21:38
// File constant3
//
#include <stdio.h>
int main() {
    const int a;
    int const a2;
    int *pi = (int *) &a;
    *pi = 19;
    printf("%d\n", a);//19
    pi = (int *) &a2;
    *pi = 20;
    printf("%d\n", a2);//20
    return 0;
}

const修飾的變量真的不能改嗎?

  • const修飾的變量其實是可以改的(前提是gcc環境下)。
  • 在某些單片機環境下,const修飾的變量是不可以改的。const修飾的變量到底能不能真的被修改,取決於具體的環境,C語言本身並沒有完全嚴格一致的要求。
  • gcc中,const是通過編譯器在編譯的時候執行檢查來確保實現的(也就是說const類型的變量不能改是編譯錯誤,不是運行時錯誤。)所以我們只要想辦法騙過編譯器,就可以修改const定義的常量,而運行時不會報錯。
  • 更深入一層的原因,是因為gccconst類型的常量也放在了data段,其實和普通的全局變量放在data段是一樣實現的,只是通過編譯器認定這個變量是const的,運行時並沒有標記const標誌,所以只要騙過編譯器就可以修改了。

const究竟應該怎麽用

const是在編譯器中實現的,編譯時檢查,並非不能騙過。所以在C語言中使用const,就好象是一種道德約束而非法律約束,所以大家使用const時更多是傳遞一種信息,就是告訴編譯器、也告訴讀程序的人,這個變量是不應該也不必被修改的。

如何區分常量指針和指針常量

那如何區分這幾類呢? 帶兩個const的肯定是指向常量的常指針,很容易理解,主要是如何區分常量指針和指針常量:

  • 一種方式是看 * 和 const 的排列順序,比如

    int const* p;   //const * 即常量指針
    const int* p;   //const * 即常量指針
    int* const p;   //* const 即指針常量
  • 還一種方式是看const離誰近,即從右往左看,比如

    int const* p;   //const修飾的是*p,即*p的內容不可通過p改變,但p不是const,p可以修改,*p不可修改;
    const int* p;   //同上
    int* const p;   //const修飾的是p,p是指針,p指向的地址不能修改,p不能修改,但*p可以修改;
  1. const int p;
  2. const int* p;
  3. int const* p;
  4. int * const p;
  5. const int * const p;
  6. int const * const p;

第一種是常量整數,沒什麽好說的。後面五種是指針,有一個簡便的辦法記憶。從右往左讀,遇到p就替換成“p is a ”遇到, *就替換成“point to”。比如說②,讀作:p is a point to int const.p是一個指向整型常量的指針。③讀作:p is a point to const int.意思跟②相同。④讀作:p is a const point to int.p是一個常量指針,指向整型。⑤讀作:p is a const point to int const.⑥讀作:p is a const point to const int.⑤和⑥的意思相同,p都是常量指針,指向整型常量。

See

  • http://www.cnblogs.com/zhangfeionline/p/5882790.html
  • http://www.cnblogs.com/lizhenghn/p/3630405.html
  • https://www.zhihu.com/question/19829354
  • http://www.kuqin.com/language/20090322/41869.html

All rights reserved

理解常量指針與指針常量?