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

constant

*前面的是對被指向對象的修飾,*後面的是對指針自己的修飾html

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

定義:

又叫常指針,能夠理解爲常量的指針,指向的是個常量指針

關鍵點:

  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;
}

指針常量(指針自己是常量)

定義:

本質是一個常量,而用指針修飾它。指針常量的值是指針,這個值由於是常量,因此不能被賦值。code

關鍵點:

  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;
}

指向常量的常指針

定義:

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

關鍵點:

  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時更可能是傳遞一種信息,就是告訴編譯器、也告訴讀程序的人,這個變量是不該該也沒必要被修改的。blog

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

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

  • 一種方式是看 * 和 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都是常量指針,指向整型常量。get

See

All rights reserved

相關文章
相關標籤/搜索