11深刻理解C指針之---指針和常量

  該系列文章源於《深刻理解C指針》的閱讀與理解,因爲本人的見識和知識的欠缺可能有誤,還望你們批評指教。安全

  指針做爲C語言的左膀右臂,使用方便,修改容易,引用數據快速都是頗有前景的應用。C語言中常量是值不能改變的量,因爲在某些應用中,想要阻止沒有受權的數據的修改時,就須要將指針和常量結合起來。spa

  先看如下代碼:指針

 1 #include <stdio.h>                                                                                                  
 2 
 3 int main(int argc, char **argv)
 4 {
 5     int iVar1 = 30;
 6     int *ptrVar1 = &iVar1;
 7     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
 8     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
 9 
10     iVar1++;
11     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
12     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
13 
14     (*ptrVar1)++;
15     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
16     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
17 
18     return 0;
19 }

  代碼結果:code

iVar1 value: 30 and iVar1 address: 0x5b483c1c
*ptrVar1 value: 30 ptrVar1 value: 0x5b483c1c and ptrVar1 address: 0x5b483c10
iVar1 value: 31 and iVar1 address: 0x5b483c1c
*ptrVar1 value: 31 ptrVar1 value: 0x5b483c1c and ptrVar1 address: 0x5b483c10
iVar1 value: 32 and iVar1 address: 0x5b483c1c
*ptrVar1 value: 32 ptrVar1 value: 0x5b483c1c and ptrVar1 address: 0x5b483c10

  經過以上代碼不難發現,將指針指向變量後,不管經過指針或變量均可以輕鬆修改變量。有時只是想利用指針的便利,而又不想承擔指針能夠修改變量的風險是,與const結合無疑是最好的。blog

  1、const修飾指針定義:經過指針引用的方式修改變量將會被禁止

    一、特徵:

      1)、提供一種特殊的方式來操縱數據

      2)、指針的值能夠改變

      3)、不能經過指針改變指向變量的值io


    二、兩種形式,兩種形式徹底同樣的:編譯

      1)、int const *ptrVar1;

      2)、const int  *ptrVar1;
      
  將代碼1的第6行代碼改成以下:class

6     int const *ptrVar1 = &iVar1;

  代碼編譯錯誤以下:test

test11_01.c:14:12: 錯誤:令只讀位置‘*ptrVar1’自增
  (*ptrVar1)++;
            ^~

  只有將第14行以下代碼註釋掉,才能經過編譯:變量

(*ptrVar1)++;

  再看以下代碼段:

 1 #include <stdio.h>
 2 
 3 int main(int argc, char **argv)
 4 {
 5     int iVar1 = 30;
 6     int iVar2 = 90;
 7     int const *ptrVar1 = &iVar1;
 8     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
 9     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
10 
11     iVar1++;
12     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
13     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
14 
15     ptrVar1 = &iVar2;
16     printf("iVar2 value: %d and iVar2 address: %#x\n", iVar2, &iVar2);                                              
17     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
18 
19     return 0;
20 }

  結果以下:

iVar1 value: 30 and iVar1 address: 0xf15c983c
*ptrVar1 value: 30 ptrVar1 value: 0xf15c983c and ptrVar1 address: 0xf15c9830
iVar1 value: 31 and iVar1 address: 0xf15c983c
*ptrVar1 value: 31 ptrVar1 value: 0xf15c983c and ptrVar1 address: 0xf15c9830
iVar2 value: 90 and iVar2 address: 0xf15c9838
*ptrVar1 value: 90 ptrVar1 value: 0xf15c9838 and ptrVar1 address: 0xf15c9830

  根據定義,容易知道因爲const修飾的是*ptrVar1,是指針的引用,所以沒法經過指針引用修改變量的值,可是依舊能夠經過變量賦值修改變量,並且指針變量能夠指向其餘變量如iVar2等。

  2、const修飾指針定義:能夠經過指針引用的方式修改變量,禁止指針指向其餘變量

    一、特徵:

      1)、提供一種特殊的方式來操縱數據

      2)、指針的值不能夠改變

      3)、經過指針改變指向變量的值


    二、應用形式:

      1)、int  * const ptrVar1;

  將代碼2的第6行代碼改成以下:

6     int * const ptrVar1 = &iVar1;

  代碼編譯錯誤以下:

test11_01.c:15:10: 錯誤:向只讀變量‘ptrVar1’賦值
  ptrVar1 = &iVar2;

  只有將第15行以下代碼註釋掉或改成(*ptrVar1)++,才能經過編譯:

ptrVar1 = &iVar2;

  請看以下具體代碼段:

 1 #include <stdio.h>
 2 
 3 int main(int argc, char **argv)
 4 {
 5     int iVar1 = 30;
 6     int *const ptrVar1 = &iVar1;                                                                                    
 7     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
 8     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
 9 
10     iVar1++;
11     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
12     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
13 
14     //ptrVar1 = &iVar2;
15     (*ptrVar1)++;
16     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
17     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
18 
19     return 0;
20 }

  根據定義,容易知道因爲const修飾的是ptrVar1,是指針變量自身,指針的值不能改變。所以能夠經過指針引用修改變量的值,也能夠經過變量賦值修改變量,可是指針變量不能夠指向其餘變量如iVar2等。

  3、const修飾指針定義,同時修改指針變量:經過指針引用的方式修改變量將會被禁止,指針也不能指向其餘變量

    一、特徵:

      1)、提供一種特殊的方式來操縱數據

      2)、指針的值不能夠改變

      3)、不可經過指針改變指向變量的值


    二、應用形式:

      1)、int const  * const ptrVar1;

  代碼以下:

   1 #include <stdio.h>
   2 
   3 int main(int argc, char **argv)
   4 {
   5     int iVar1 = 30;
   6     int iVar2 = 90;                                                                                               
   7     int const *const ptrVar1 = &iVar1;
   8     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
   9     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
  10 
  11     iVar1++;
  12     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
  13     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
  14 
>>15     ptrVar1 = &iVar2;
  16     //(*ptrVar1)++;
  17     printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
  18     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1);
  19 
  20     return 0;
  21 }

  保留第15行代碼,編譯錯誤以下:

test11_01.c:15:10: 錯誤:向只讀變量‘ptrVar1’賦值
  ptrVar1 = &iVar2;
          ^

  保留第16行代碼,編譯錯誤以下:

test11_01.c:16:12: 錯誤:令只讀位置‘*ptrVar1’自增
  (*ptrVar1)++;
            ^~

  因而可知,經過兩個const的修飾,使得不管是指針變量的值,仍是指針變量的解引用值都沒法改變,能夠有效提升數據的安全性。

相關文章
相關標籤/搜索