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

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

  先看以下代码:

  #include <stdio.h>                                                                                                  

  int main(int argc, char **argv)
{
int iVar1 = ;
int *ptrVar1 = &iVar1;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); iVar1++;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); (*ptrVar1)++;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); return ;
}

  代码结果:

iVar1 value:  and iVar1 address: 0x5b483c1c
*ptrVar1 value: ptrVar1 value: 0x5b483c1c and ptrVar1 address: 0x5b483c10
iVar1 value: and iVar1 address: 0x5b483c1c
*ptrVar1 value: ptrVar1 value: 0x5b483c1c and ptrVar1 address: 0x5b483c10
iVar1 value: and iVar1 address: 0x5b483c1c
*ptrVar1 value: ptrVar1 value: 0x5b483c1c and ptrVar1 address: 0x5b483c10

  通过以上代码不难发现,将指针指向变量后,无论通过指针或变量都可以轻松修改变量。有时只是想利用指针的便利,而又不想承担指针可以修改变量的风险是,与const结合无疑是最好的。

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

    1、特征:

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

      2)、指针的值可以改变

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

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

      1)、int const *ptrVar1;

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

     int const *ptrVar1 = &iVar1;

  代码编译错误如下:

test11_01.c::: 错误:令只读位置‘*ptrVar1’自增
(*ptrVar1)++;
^~

  只有将第14行如下代码注释掉,才能通过编译:

(*ptrVar1)++;

  再看如下代码段:

  #include <stdio.h>

  int main(int argc, char **argv)
{
int iVar1 = ;
int iVar2 = ;
int const *ptrVar1 = &iVar1;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); iVar1++;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); ptrVar1 = &iVar2;
printf("iVar2 value: %d and iVar2 address: %#x\n", iVar2, &iVar2);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); return ;
}

  结果如下:

iVar1 value:  and iVar1 address: 0xf15c983c
*ptrVar1 value: ptrVar1 value: 0xf15c983c and ptrVar1 address: 0xf15c9830
iVar1 value: and iVar1 address: 0xf15c983c
*ptrVar1 value: ptrVar1 value: 0xf15c983c and ptrVar1 address: 0xf15c9830
iVar2 value: and iVar2 address: 0xf15c9838
*ptrVar1 value: 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;

  请看如下具体代码段:

  #include <stdio.h>

  int main(int argc, char **argv)
{
int iVar1 = ;
int *const ptrVar1 = &iVar1;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); iVar1++;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); //ptrVar1 = &iVar2;
(*ptrVar1)++;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); return ;
}

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

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

    1、特征:

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

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

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

    2、应用形式:

      1)、int const  * const ptrVar1;

  代码如下:

    #include <stdio.h>

    int main(int argc, char **argv)
{
int iVar1 = ;
int iVar2 = ;
int const *const ptrVar1 = &iVar1;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); iVar1++;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); >> ptrVar1 = &iVar2;
//(*ptrVar1)++;
printf("iVar1 value: %d and iVar1 address: %#x\n", iVar1, &iVar1);
printf("*ptrVar1 value: %d ptrVar1 value: %#x and ptrVar1 address: %#x\n", *ptrVar1, ptrVar1, &ptrVar1); return ;
}

  保留第15行代码,编译错误如下:

test11_01.c::: 错误:向只读变量‘ptrVar1’赋值
ptrVar1 = &iVar2;
^

  保留第16行代码,编译错误如下:

test11_01.c::: 错误:令只读位置‘*ptrVar1’自增
(*ptrVar1)++;
^~

  由此可见,通过两个const的修饰,使得无论是指针变量的值,还是指针变量的解引用值都无法改变,可以有效提高数据的安全性。

  

11深入理解C指针之---指针和常量的更多相关文章

  1. 00深入理解C指针之--- 指针之外

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. C语言从诞生之初就非常善于和硬件打交道,经过这么多年的发展之后,其灵活性和超强的特征是 ...

  2. 10深入理解C指针之---指针运算和比较

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针运算有很多种,主要有指针的声明*.指针的解引*.指针指向(*).或->.指针 ...

  3. 从四个属性的角度来理解C语言的指针也许会更好理解

    文章会在文末更新! 关于指针是什么,很多教材已经作出了定义,大多数都会定义为"存放变量内存地址的变量".从这句话中我觉得除了让我知道这个定义有11个字以外,其他就没什么用了.我个人 ...

  4. 02深入理解C指针之---指针类型和值

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 1.指针的类型: 可以在声明指针时,指定指针的类型,例如: (1)void *x  声 ...

  5. 06深入理解C指针之---指针操作和比较

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针作为一种特殊类型的变量,必须遵守C语言中变量先声明后使用的原则.本节内容中指针的操 ...

  6. 理解C语言中指针的声明以及复杂声明的语法

    昨天刚把<C程序设计语言>中"指针与数组"章节读完,最终把心中的疑惑彻底解开了.如今记录下我对指针声明的理解.顺便说下怎样在C语言中创建复杂声明以及读懂复杂声明. 本文 ...

  7. C语言指针的理解以及指针的指针的理解

    指针指向的是内存地址编号,内存地址编号指向的是对应的内容. 我们需要一个变量,来储存内存地址编号,这个变量的值是一个内存地址编号,但是我们可以通过修改变量的值,来不断的改变内存地址编号. 但是,我们如 ...

  8. 这样子来理解C语言中指针的指针

    友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...

  9. 理解git 中的HEAD指针&branch指针

    理解git 中的HEAD指针&branch指针 Yooye关注 2019.02.28 10:44:32字数 492阅读 668 HEAD指针 使用git checkout 来移动HEAD指针, ...

  10. 深入理解C语言-函数指针

    函数指针在C++中有着重要的应用,函数的函数名其本质就是代表一个地址,这个地址叫做函数入口,得到这个地址就可以对这个函数进行各种操作. 函数类型基础 函数三要素: 名称.参数.返回值 C语言中的函数有 ...

随机推荐

  1. 救援(BFS)

    题目描述: 在你的帮助下,Oliver终于追到小X了,可有一天,坏人把小X抓走了.这正是Oliver英雄救美的时候.所以,Oliver又找到哆啦A梦,借了一个机器,机器显示出一幅方格地图,它告诉Oli ...

  2. 【AC自动机】bzoj4327: JSOI2012 玄武密码

    题目思路没话讲:主要是做题时候的细节和经验 Description 在美丽的玄武湖畔,鸡鸣寺边,鸡笼山前,有一块富饶而秀美的土地,人们唤作进香河.相传一日,一缕紫气从天而至,只一瞬间便消失在了进香河中 ...

  3. angular4使用代理

    1. 在angular-cli项目根目录下创建proxy.config.json { "/api/v1": { "target": "http://1 ...

  4. Yii2 HelloWord

    一.安装Yii2 可以直接官网或github下载: https://github.com/yiisoft/yii2 下载完后进入项目的web/目录,入口文件为该目录下的index.php,这里直接启用 ...

  5. laravel连接数据库提示mysql_connect() :Connection refused...

    在.env配置文件中填写了正确的数据库连接配置的情况下连接还是出错了,明显提示的不是密码错误,那就看看端口吧, DB_HOST=127.0.0.1 DB_PORT= DB_DATABASE=test ...

  6. 【linux】【安全】服务器安全建议

    引用自 <鸟哥的linux私房菜-服务器篇>  http://cn.linux.vbird.org/linux_server/0210network-secure_1.php 建立完善的登 ...

  7. 【mac】【转发】Mac系统升级后,按大小写键没反应了,切换大小写的灯不亮了

    Mac系统升级后发现caps lock 锁定大小写的键,失灵了,居然可以用来切换输入法了,经过一排查后, 使用以下几种方法处理: 方式一:长按 caps lock 键,来切换大小写 方式二:caps ...

  8. SQL_2_查询Select语句的使用

    查询一词在SQL中并不是很恰当,在SQL中查询除了向数据库提出问题之外,还可以实现下面的功能: 1>建立或删除一个表 2>插入.修改.或删除一个行或列 3>用一个特定的命令从几个表中 ...

  9. 像玩魔兽一样编程——谈VS2010键盘流

    早年在学校里的时候,经常玩War3,那时候很痴迷,也经常看sky.moon的一些第一视角,有的时候也会模仿模仿...好吧,往事不堪回首,现在工作了,谈一谈.Net程序猿使用VS的键盘流,如果你不知道s ...

  10. SPOJ FFT TSUM

    第一道FFT的题目. 在网上找了很多FFT的资料,但一直都看不懂,最后是看算法导论学的FFT,算法导论上面写的很详细,每一步推导过程都有严格的证明. 下面说这道题 题意: 给一个序列s,有n个不互相同 ...