【原创】浅谈指针(五)const和指针
前言
过了几个月再次更新。最近时间也不多了,快要期中考试了,暂且先少写一点吧。
本文仅在博客园发布,如在其他平台发现均为盗取,请自觉支持正版。
练习题
我们先来看几道题目。如果这几道题都不会的话,就先好好复习我写的前四篇文章吧,这一章是肯定看不懂的。
- 1.使用指针编写swap函数。(经典例题)
答案
void swap(int *a,int *b){
int t=*a;*a=*b;*b=t;
}
- 2.已知数组a[10][10],交换该数组的第1和第3行。
答案
实际上,二维数组的每一行都是一个单独的数组,二维数组的本质就是“数组的数组”。因此,可以使用memcpy进行数组拷贝。
int temp[10];
memcpy(temp,a[0],10*sizeof(int));
memcpy(a[0],a[2],10*sizeof(int));
memcpy(a[2],temp,10*sizeof(int));
const
const含义
const是constant的缩写,意为“常量”,事实上我们也经常用const定义常量。
但是在C语言(这里不是C++),const的含义是“只读变量”。也就是说,const就是普通变量。
我们做一个实验确认一下。(务必采用C语言编译)
#include<stdio.h>
int main(){
int *p;
const int a=5;
printf("a..%d",a);
p=&a;
*p=10;
printf("a..%d",a);
}
先说一下C++为什么不通过编译,因为C++对于类型比较严格,编译上述代码会出这个错误:
error: invalid conversion from 'const int' to 'int' [-fpermissive]
因此,如果手头只有C++环境的话,请务必开-fpermissive选项。
在C语言下,输出结果是a..5和a..10。在C++下,即使开了fpermissive,结果仍然是a..5和a..5。
我们来阅读一下程序。我们使用指针的形式,将a的地址赋值给p,那么p所指向的就是a。但是由于p不带const(const指针的问题将会于下一节叙述),*p可以被修改,那么a就理所当然被修改为10了。
但是在C++中,const就是指常量,在处理a的时候,编译器会自动的把a理解为5,不再去读取a所在的内存了。因此,即使a对应的内存被修改,a输出结果仍然为5。
如果把第二个printf语句中,a改为*p,输出为10。这再次证明了C++这一特性。
const内存区域
如果把const int a一句放到main以外成为全局变量,结果又会如何?大家可以自行尝试一下。
结果是运行时错误,segmentation fault段错误。
这是因为,全局变量的const,存储的区域是配置在内存的只读区域的,修改会出问题。而局部变量存储的区域在栈上,和其他普通变量在一起,因此可以任意修改。
如果尝试输出全局变量和局部变量的地址,我们发现,两个地址相差很远。
0x402004 0x7ffd9a34094c
const和指针
声明部分
(以下转自我之前写的C语言常见误区)
关于const和指针连在一起,经常让初学者们摸不着头脑。
例如下面几句:
const char *p
char const *p
char* const p
const char* const p
它们各有什么区别?
我这里曾经从《征服C指针》看到了几条非常好的内容,在此给大家分享一下:
因为C语言是美国人发明的,最好还是用英语来读(声明语句)。
规则:从后往前倒序,如果遇到*号,就加上“pointer to”,如果有const,就追加“read-only”。
const在前面和在后面完全相同。
例如,对const char *p进行翻译:
首先看到p:p is
然后是*:p is pointer to
然后是char:p is pointer to char
然后是const:p is pointer to read-only char
翻译为中文:p是指向只读的char的指针
按照这种方式解释,我们对上面四个语句解释如下:
p is pointer to read-only char
p is pointer to read-only char
p is read-only pointer to char
p is read-only pointer to read-only char
照这样,我们得出结论:
const char* p 和char const* p含义完全相同,表示指向的字符是不可变的。
char* const p表示指针自身不可变,指向的字符可变。
而最后一个,指向的字符和指针自身都不可变。
应用
定义字符串常量,我们一般使用:
const char *str=...
这类的语句。指向的字符是不可改变的。
但注意下面的代码:
#include<stdio.h>
#include<string.h>
struct test{
int a,b;
char str[10];
};
int main(){
const struct test a={1,2,"hello"};
strcpy(a.str,"abc");
printf("%s",a.str);
}
虽然结构体a是const的,因此str本身不可改变,但是str指向的字符仍然可以改变!图示如下:

函数参数的const
比较简单。例如strcpy的声明:
void strcpy(char *dest, const char *src);
在此处,const表示在函数内部,src的值不可改动。并非表示传入的参数一定是常量。
很多函数都包含输入参数和输出参数。与其使用繁杂的注释,例如:
/*
src (i) 参数提供的输入字符串
dest (o) 复制到的字符串
*/
使用i,o等标记,还不如使用const,后者在函数中不小心修改src的时候,还会发出警告。
以上参考《征服C指针》。
全文完。
【原创】浅谈指针(五)const和指针的更多相关文章
- 转: 浅谈C/C++中的指针和数组(二)
转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...
- 转:浅谈C/C++中的指针和数组(一)
再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...
- [原创]浅谈如何使用gcc开发NT核心驱动程序
原文链接:[原创]浅谈如何使用gcc开发NT核心驱动程序 一谈到在 Win NT 下开发核心驱动程序,可能不少人首先都会想到微软“正统”的VC来.诚然,用VC 配合 WINDDK 的确工作的不错,但或 ...
- [原创]浅谈移动互联网App兼容性测试
[原创]浅谈移动互联网App兼容性测试 今天要谈的话题,估计各位测试都有感受,移动互联网App兼容性测试,我们到底测试覆盖如何去挑选机型?具体移动App兼容性测试如何开展?是不是应引进像testin这 ...
- [原创]浅谈IT人如何做理财规划
[原创]浅谈IT人如何做理财规划 鱼哥博客上多数写的是技术和管理相关,但很少有理财等话题,今天抽空来谈谈IT人如何做理财规划,如果要想学习理财,我想很有名的“标准普尔家庭资产象限图”上值得每个学习和理 ...
- [原创]浅谈Web UI自动化测试
[原创]浅谈Web UI自动化测试 Web UI自动化测试相信大家都不陌生,今天来谈谈这个,我最早接触自动化测试时大约是在2004年,2006年当时在腾讯财付通算是开始正式接触自动化测试,之所以是正式 ...
- [原创] 浅谈ETL系统架构如何测试?
[原创] 浅谈ETL系统架构如何测试? 来新公司已入职3个月时间,由于公司所处于互联网基金行业,基金天然固有特点,基金业务复杂,基金数据信息众多,基金经理众多等,所以大家可想一下,基民要想赚钱真不容易 ...
- [原创]浅谈移动App安全测试
[原创]浅谈移动App安全测试 移动互联网很火,就像当年互联网兴起一样,这几天和朋友在沟通交流,谈到一个话题,你们做金融App钱放在你们哪边安全不?会不会你们做的移动App不安全,让人盗了里面的资金, ...
- [原创]浅谈H5页面性能优化方法
[原创]浅谈H5页面性能优化方法 前阶段公司H5页面性能测试,其中测试时也发现了一些性能瓶颈问题,接下来我们在来谈谈H5页面性能优化,仅仅是一些常用H5页面性能优化措施,其实和Web页面性能优化思路大 ...
- [原创]浅谈H5页面性能测试
[原创]浅谈H5页面性能测试 H5页面我想各位都不陌生,随着移动互联网兴起,不管是App,还是H5都火起来了,最突出的2个表现是ios/android/前端等工程师薪水大涨,尤其是资深前端工程师40W ...
随机推荐
- C语言实现线程池功能
1. 线程池基本原理 2. 线程池C语言实现 2.1 线程池的数据结构 #include <stdio.h> #include <pthread.h> #include < ...
- 第04课:使用 VS 管理开源项目
本节课将介绍 Redis 项目在 Linux 系统中使用 gdb 去调试,这里的调试环境是 CentOS 7.0,但是通常情况下对于 C/C++ 项目我一般习惯使用 Visual Studio 去做项 ...
- GRE隧道协议
1. GRE协议简介 GRE(General Routing Encapsulation ,通用路由封装)是对某些网络层协议(如IP和IPX)的数据报文进行封装,使这些被封装的报文能够在另一网络层协议 ...
- Identity用户管理入门五(登录、注销)
一.建立LoginViewModel视图模型 using System.ComponentModel.DataAnnotations; namespace Shop.ViewModel { publi ...
- 前后端数据交互(八)——请求方法 GET 和 POST 区别
WEB 开发同学一看 get 和 post 请求方法的区别,第一感觉都是 So easy! 学习ajax.fetch.axios时,发送网络请求携带参数时,都需要分别处理get和post的参数.所以我 ...
- mysql升级-rpm安装
mysql版本5.7.29升级到5.7.30 由于我们安装mysql的方式是通过mysql-5.7.29-1.el7.x86_64.rpm-bundle.tar中的rpm包安装:rpm -Uvh my ...
- lua中的sleep实现
这篇文章主要介绍了Lua中实现sleep函数功能的4种方法,本文讲解了在一个死循环中设置一个跳出条件方法.调用系统的sleep函数法.Windows下ping命令法.socket库中select函数法 ...
- js根据日期获取所在周
一.获取时间所在周的周一.周五 function getFirstLastDay (time) { let date = new Date(time) let Time = date.getTime( ...
- Cookie和Session的介绍与认识
Cookie: cookie是一种客户端的状态管理技术. 当浏览器向服务器发送请求的时候,服务器会将少量的数据以set-cookie消息头的方式发送给浏览器,当浏览器再次访问服务器时,会将这些数据以c ...
- VBox 虚拟机安装 Openwrt 做旁路由
VBox 虚拟机安装 Openwrt 做旁路由 需求:开个虚拟机做旁路由,电脑把网关设置成旁路由地址,用它跑个上网或其他什么东西. 安装及配置过程简述 这件事流程很简单,总结起来主要有以下几点: 安装 ...