前言

过了几个月再次更新。最近时间也不多了,快要期中考试了,暂且先少写一点吧。

本文仅在博客园发布,如在其他平台发现均为盗取,请自觉支持正版。

练习题

我们先来看几道题目。如果这几道题都不会的话,就先好好复习我写的前四篇文章吧,这一章是肯定看不懂的。

  • 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和指针的更多相关文章

  1. 转: 浅谈C/C++中的指针和数组(二)

    转自:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组 ...

  2. 转:浅谈C/C++中的指针和数组(一)

    再次读的时候实践了一下代码,结果和原文不一致 error C2372: 'p' : redefinition; different types of indirection 不同类型的间接寻址 /// ...

  3. [原创]浅谈如何使用gcc开发NT核心驱动程序

    原文链接:[原创]浅谈如何使用gcc开发NT核心驱动程序 一谈到在 Win NT 下开发核心驱动程序,可能不少人首先都会想到微软“正统”的VC来.诚然,用VC 配合 WINDDK 的确工作的不错,但或 ...

  4. [原创]浅谈移动互联网App兼容性测试

    [原创]浅谈移动互联网App兼容性测试 今天要谈的话题,估计各位测试都有感受,移动互联网App兼容性测试,我们到底测试覆盖如何去挑选机型?具体移动App兼容性测试如何开展?是不是应引进像testin这 ...

  5. [原创]浅谈IT人如何做理财规划

    [原创]浅谈IT人如何做理财规划 鱼哥博客上多数写的是技术和管理相关,但很少有理财等话题,今天抽空来谈谈IT人如何做理财规划,如果要想学习理财,我想很有名的“标准普尔家庭资产象限图”上值得每个学习和理 ...

  6. [原创]浅谈Web UI自动化测试

    [原创]浅谈Web UI自动化测试 Web UI自动化测试相信大家都不陌生,今天来谈谈这个,我最早接触自动化测试时大约是在2004年,2006年当时在腾讯财付通算是开始正式接触自动化测试,之所以是正式 ...

  7. [原创] 浅谈ETL系统架构如何测试?

    [原创] 浅谈ETL系统架构如何测试? 来新公司已入职3个月时间,由于公司所处于互联网基金行业,基金天然固有特点,基金业务复杂,基金数据信息众多,基金经理众多等,所以大家可想一下,基民要想赚钱真不容易 ...

  8. [原创]浅谈移动App安全测试

    [原创]浅谈移动App安全测试 移动互联网很火,就像当年互联网兴起一样,这几天和朋友在沟通交流,谈到一个话题,你们做金融App钱放在你们哪边安全不?会不会你们做的移动App不安全,让人盗了里面的资金, ...

  9. [原创]浅谈H5页面性能优化方法

    [原创]浅谈H5页面性能优化方法 前阶段公司H5页面性能测试,其中测试时也发现了一些性能瓶颈问题,接下来我们在来谈谈H5页面性能优化,仅仅是一些常用H5页面性能优化措施,其实和Web页面性能优化思路大 ...

  10. [原创]浅谈H5页面性能测试

    [原创]浅谈H5页面性能测试 H5页面我想各位都不陌生,随着移动互联网兴起,不管是App,还是H5都火起来了,最突出的2个表现是ios/android/前端等工程师薪水大涨,尤其是资深前端工程师40W ...

随机推荐

  1. C# 实现图片上传

    C# 实现图片上传 C#实现图片上传: 通过页面form表单提交数据到动作方法,动作方法实现保存图片到指定路径,并修改其文件名为时间格式 页面设置 这里使用的模板MVC自带的模板视图 <h2&g ...

  2. Linux复习笔记-001-进程的管理

    1.什么是进程? 进程是已经启动的可执行的程序运行实例. 程序是二进制文件,静态 ./bin/date/ /usr/sbin/ 进程:是程序运行的过程 2.Linux为1的进程? centos5或6为 ...

  3. Django使用tinymce富文本编辑器

    1 - 安装 pip install django-tinymce==2.6.0 2 - 注册app INSTALLED_APPS = ( ... 'tinymce', ) 3 - 在setting中 ...

  4. python glob.glob()

    glob()函数可以将某目录下所有跟通配符模式相同的文件放到一个列表中,有了这个函数,我们再想生成所有文件的列表就不需要使用for循环遍历目录了,直接使用glob.glob(path+pattern) ...

  5. Tars | 第5篇 基于TarsGo Subset路由规则的Java JDK实现方式(上)

    目录 前言 1. 修改.tars协议文件 1.1 Go语言修改部分 1.2 修改地方的逻辑 1.3 通过协议文件自动生成代码 2. [核心]增添Subset核心功能 2.1 Go语言修改部分 2.2 ...

  6. QT程序打包成多平台可执行文件

    一.简述 QT项目开发完成后,需要打包发布程序,在实际生产中不可能把源码发给别人,所以需要将源码打包正可执行文件或者安装程序. 二.设置应用图标 把 ico 文件放到源代码目录下,在QT项目中的'.p ...

  7. 基于Tensorflow + Opencv 实现CNN自定义图像分类

    摘要:本篇文章主要通过Tensorflow+Opencv实现CNN自定义图像分类案例,它能解决我们现实论文或实践中的图像分类问题,并与机器学习的图像分类算法进行对比实验. 本文分享自华为云社区< ...

  8. 一起学习PHP中GD库的使用(二)

    在日常的开发过程中,GD 库最常用的功能就是帮我们对图片进行一些处理,当然,除了处理已有的图片之外,它也可以直接来画图,就像我们最常见的图片验证码.今天的内容主要就是和画图有关,所以最后我们也会做一个 ...

  9. symfony2中mysql和mongodb的增删改查总结

    https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manip ...

  10. linux centos windows服务器修改数据库最大连接数的方法

    1.可查询数据库最大连接数 show variables like '%max_connections%'; 2.修改数据库最大连接数,最大限制上限为16384. 找到数据库配置文件my.cnf,在配 ...