11深入理解C指针之---指针和常量
该系列文章源于《深入理解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指针之---指针和常量的更多相关文章
- 00深入理解C指针之--- 指针之外
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. C语言从诞生之初就非常善于和硬件打交道,经过这么多年的发展之后,其灵活性和超强的特征是 ...
- 10深入理解C指针之---指针运算和比较
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针运算有很多种,主要有指针的声明*.指针的解引*.指针指向(*).或->.指针 ...
- 从四个属性的角度来理解C语言的指针也许会更好理解
文章会在文末更新! 关于指针是什么,很多教材已经作出了定义,大多数都会定义为"存放变量内存地址的变量".从这句话中我觉得除了让我知道这个定义有11个字以外,其他就没什么用了.我个人 ...
- 02深入理解C指针之---指针类型和值
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 1.指针的类型: 可以在声明指针时,指定指针的类型,例如: (1)void *x 声 ...
- 06深入理解C指针之---指针操作和比较
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针作为一种特殊类型的变量,必须遵守C语言中变量先声明后使用的原则.本节内容中指针的操 ...
- 理解C语言中指针的声明以及复杂声明的语法
昨天刚把<C程序设计语言>中"指针与数组"章节读完,最终把心中的疑惑彻底解开了.如今记录下我对指针声明的理解.顺便说下怎样在C语言中创建复杂声明以及读懂复杂声明. 本文 ...
- C语言指针的理解以及指针的指针的理解
指针指向的是内存地址编号,内存地址编号指向的是对应的内容. 我们需要一个变量,来储存内存地址编号,这个变量的值是一个内存地址编号,但是我们可以通过修改变量的值,来不断的改变内存地址编号. 但是,我们如 ...
- 这样子来理解C语言中指针的指针
友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...
- 理解git 中的HEAD指针&branch指针
理解git 中的HEAD指针&branch指针 Yooye关注 2019.02.28 10:44:32字数 492阅读 668 HEAD指针 使用git checkout 来移动HEAD指针, ...
- 深入理解C语言-函数指针
函数指针在C++中有着重要的应用,函数的函数名其本质就是代表一个地址,这个地址叫做函数入口,得到这个地址就可以对这个函数进行各种操作. 函数类型基础 函数三要素: 名称.参数.返回值 C语言中的函数有 ...
随机推荐
- tempfs详解
致因 在平常工作中,我们经常需要查看Linux服务器磁盘挂载使用情况,可以使用df命令,不知大家注意到没有,我们使用此命令除了会查看到系统盘以及数据盘挂载情况,还会看到一个tmpfs也在挂载. [ro ...
- vue之列表循环
文档:https://cn.vuejs.org/v2/guide/list.html 当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略.如果数据项的顺序被改变, ...
- 通过composer安装阿里大于接口扩展
# 安装laravel阿里大鱼服务 composer require iscms/alisms-for-laravel laravel配置 # 注册服务 # 在config\app.php文件中找到P ...
- EditPlus 比较完整的快捷键记录
FileFtpUpload Ctrl+Shift+S 上传文件到FTP 服务器 FileNew Ctrl+N 新建普通的文本文档 FileNewHtml Ctrl+Shift+N 创建一个空白的 HT ...
- GoF23种设计模式之行为型模式之中介者模式
一.概述 使用一个中介对象来封装一系列的对象交互.中介者让各个对象无需显式地相互引用,从而达到解耦的效果.并且可以独立地改变它们之间的交互.二.适用性1.当一组对象以定义良好但复杂通信的时候.产生的相 ...
- Python学习笔记:输入输出,注释,运算符,变量,数字类型,序列,条件和循环控制,函数,迭代器与生成器,异常处理
输入输出 输入函数input()和raw_input() 在Python3.x中只有input()作为输入函数,会将输入内容自动转换str类型: 在Python2.x中有input()和raw_inp ...
- Ubuntu 15.04 安装配置 Qt + SQLite3
序 最近需要在Ubuntu下使用Qt开发项目,选择简单小巧的SQLite数据库,现将安装配置以及简单操作记录如下,以便日后查阅. 安装Qt CMake和Qt Creator是Linux下开发C++程序 ...
- poj-3278 catch that cow(搜索题)
题目描述: Farmer John has been informed of the location of a fugitive cow and wants to catch her immedia ...
- POJ 1791 Parallelogram Counting(求平行四边形数量)
Description There are n distinct points in the plane, given by their integer coordinates. Find the n ...
- Wordpress入门笔记
简单介绍一下wordpress个人操作,建议安装中文版. 登入后台管理者页面, 浏览器地址栏输入 (线上) http://XXXX.com/wp-login.php (本地) ht ...