zoukankan      html  css  js  c++  java
  • 11深入理解C指针之---指针和常量

      该系列文章源于《深入理解C指针》的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教。

      指针作为C语言的左膀右臂,使用方便,修改容易,引用数据快速都是很有前景的应用。C语言中常量是值不能改变的量,由于在某些应用中,想要阻止没有授权的数据的修改时,就需要将指针和常量结合起来。

      先看以下代码:

     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
    ", iVar1, &iVar1);
     8     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
     9 
    10     iVar1++;
    11     printf("iVar1 value: %d and iVar1 address: %#x
    ", iVar1, &iVar1);
    12     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
    13 
    14     (*ptrVar1)++;
    15     printf("iVar1 value: %d and iVar1 address: %#x
    ", iVar1, &iVar1);
    16     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
    17 
    18     return 0;
    19 }

      代码结果:

    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结合无疑是最好的。

      一、const修饰指针定义:通过指针引用的方式修改变量将会被禁止

        1、特征:

          1)、提供一种特殊的方式来操纵数据

          2)、指针的值可以改变

          3)、不能通过指针改变指向变量的值


        2、两种形式,两种形式完全一样的:

          1)、int const *ptrVar1;

          2)、const int  *ptrVar1;
          
      将代码1的第6行代码改为如下:

    6     int const *ptrVar1 = &iVar1;

      代码编译错误如下:

    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
    ", iVar1, &iVar1);
     9     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
    10 
    11     iVar1++;
    12     printf("iVar1 value: %d and iVar1 address: %#x
    ", iVar1, &iVar1);
    13     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
    14 
    15     ptrVar1 = &iVar2;
    16     printf("iVar2 value: %d and iVar2 address: %#x
    ", iVar2, &iVar2);                                              
    17     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *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等。

      二、const修饰指针定义:可以通过指针引用的方式修改变量,禁止指针指向其他变量

        1、特征:

          1)、提供一种特殊的方式来操纵数据

          2)、指针的值不可以改变

          3)、通过指针改变指向变量的值


        2、应用形式:

          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
    ", iVar1, &iVar1);
     8     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
     9 
    10     iVar1++;
    11     printf("iVar1 value: %d and iVar1 address: %#x
    ", iVar1, &iVar1);
    12     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
    13 
    14     //ptrVar1 = &iVar2;
    15     (*ptrVar1)++;
    16     printf("iVar1 value: %d and iVar1 address: %#x
    ", iVar1, &iVar1);
    17     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
    18 
    19     return 0;
    20 }

      根据定义,容易知道由于const修饰的是ptrVar1,是指针变量自身,指针的值不能改变。因此可以通过指针引用修改变量的值,也可以通过变量赋值修改变量,但是指针变量不可以指向其他变量如iVar2等。

      三、const修饰指针定义,同时修改指针变量:通过指针引用的方式修改变量将会被禁止,指针也不能指向其他变量

        1、特征:

          1)、提供一种特殊的方式来操纵数据

          2)、指针的值不可以改变

          3)、不可通过指针改变指向变量的值


        2、应用形式:

          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
    ", iVar1, &iVar1);
       9     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
      10 
      11     iVar1++;
      12     printf("iVar1 value: %d and iVar1 address: %#x
    ", iVar1, &iVar1);
      13     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *ptrVar1, ptrVar1, &ptrVar1);
      14 
    >>15     ptrVar1 = &iVar2;
      16     //(*ptrVar1)++;
      17     printf("iVar1 value: %d and iVar1 address: %#x
    ", iVar1, &iVar1);
      18     printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x
    ", *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的修饰,使得无论是指针变量的值,还是指针变量的解引用值都无法改变,可以有效提高数据的安全性。

      

  • 相关阅读:
    审核被拒:包含隐藏功能
    iOS好的个人博客和平台网站
    免费的Git和SVN服务器
    组件化
    三方生产利器
    RSA加密解密和签名验证机制以及其区别和联系
    APP和后台接口设计规范
    树和二叉树2——输出广义表形式(带括号)二叉树
    树和二叉树1——链式二叉树基础
    计算机图形学5——Two-Dimensional Viewing and Clipping(二维线段裁剪算法)
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/6956506.html
Copyright © 2011-2022 走看看