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\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 }
代码结果:
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\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等。
二、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\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等。
三、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\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的修饰,使得无论是指针变量的值,还是指针变量的解引用值都无法改变,可以有效提高数据的安全性。
转载于:https://www.cnblogs.com/guochaoxxl/p/6956506.html
11深入理解C指针之---指针和常量相关推荐
- 10深入理解C指针之---指针运算和比较
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针运算有很多种,主要有指针的声明*.指针的解引*.指针指向(*).或->.指针 ...
- 重新学习c++--理解引用、智能指针、虚函数、模板、容器
最近几年用c和python比较多,上次用c++写程序已经是几年前的事情了.温故而知新,是时候重新学习下c++了. C++可以分成四大块去理解: C c++仍以C为基础,区块blocks.语句state ...
- 【C语言】深入理解数组和指针——初识指针
哈喽大家好,我是保护小周ღ,C语言,接下来给大家带来的是深入理解数组和指针的初识指针,这篇主要讲的是基础指针的相关知识,是博主的所见所闻,细节上的知识后面会这里面没有提,会放在后期的文章中与数组相结合 ...
- 深入理解C语言-二级指针三种内存模型
二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {&quo ...
- 深入理解指针以及二级指针(指针的指针)
前言:本文将讲解指针的定义.指针变量和普通变量的本质区别.一级指针和二级指针的关系以及如何通过二级指针修改一级指针所指向的内存.文末还附加了两个实例,帮助读者加深对二级指针的理解.本文试图通过图表的方 ...
- 理解C语言中指针的声明以及复杂声明的语法
昨天刚把<C程序设计语言>中"指针与数组"章节读完,终于把心中的疑惑彻底解开了.现在记录下我对指针声明的理解,顺便说下如何在C语言中创建复杂声明以及读懂复杂声明. 本文 ...
- 如何理解指向指针的指针?
本文由 伯乐在线 - 菜鸟浮出水 翻译自 StackOverflow.欢迎加入 技术翻译小组.转载请参见文章末尾处的要求. 问题:如何理解指向指针的指针? 我在一篇教程中看到下面这段,它描述指向指针的 ...
- 用反汇编理解指向指针的指针
用反汇编理解指向指针的指针 解释int **pp = &p ①eax = p所在的地址 ②pp = eax,即pp = p的地址 num 的地址 | 520 p | num 的地址 pp ...
- c++ 二维数组_C|数形结合理解数组指针、指针数组、一级指针来遍历二维数组
二维数组本质是也是线性存储的一维数组,各元素都是相对于基地址(首地址)的偏移,只是逻辑上的维度区分而已.或者可以理解为数组的数组,也就是说,n维数组的元素是一个n-1维数组. 需要注意的是,多维数组名 ...
- C语言基础(三):函数名、函数指针、指针函数的理解
函数指针 如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址.而且函数名表示的就是这个地址.既然是地址我们就可以定义一个指针变量来存 ...
最新文章
- python序列类型-Python数值类型和序列类型
- 跨链Cosmos(8)同构跨链交易流程
- Java 注解 拦截器
- 雷林鹏分享:YII 模型-视图-控制器(MVC)设计模式
- OpenCV系列(一)之图像平滑
- csharp语言_电脑绝技教你22天学精Csharp之第五天
- 【GNN】百度「NLP」面试的一点总结
- 全国交通智慧升级,阿里云视频上云打造高速公路“视觉中枢”
- Windows 7声卡驱动一键修复精灵3.0完美版(2009年11月9日发布)
- vCenter 6.0 web访问503错误:服务不可用,无法连接endpoint,
- 白天建筑师,晚上CG艺术家,他将建筑的华丽发挥极致
- Excel序号类操作实例
- 巨量信息流广告 “一键起量“ 功能,深度解析使用方法!
- docker php 环境实操
- Centos7安装使用libvirt
- 新冠病毒爆发如何预防?用Python模拟病毒应对策略(附代码)
- matlab 版 数独小游戏 GUI界面设计
- python中tan怎么表示_Python numpy.tan()用法及代码示例
- 中国人发假发和延伸行业市场供需与战略研究报告
- python家乡美食与旅游景点导游推荐系统django源码介绍
热门文章
- 强制杀oracle进程
- inotify 实时的Linux文件系统事件监控
- .NET Framework- 反射特性序列化(Day4)
- ora-12514: tns: 监听程序当前无法识别连接描述符中请求的服务 问题解决
- 机器学习笔记(六)支持向量机
- 在应用程序中使用虚拟内存——Windows核心编程学习手札之十五
- Python--str与repr以及eval的使用方法
- javascript (function(){})()
- Docker selenium自动化 - Python调用容器实例跑自动化查天气实例演示,docker selenium自动化环境部署过程
- 数字信号处理第一章 离散时间信号与系统