前言

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

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

练习题

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

  • 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. 性能测试工具JMeter 基础(六)—— 测试元件: 线程组

    线程组的定义: 线程组是测试计划执行的入口,所有的逻辑控制器和取样器都必须在线程组下,其他的元件根据位置的不同作用域是不同的. 线程组是每个线程都是独立运行测试脚本,一个线程组就等于一个用户,通过多个 ...

  2. C# 爬虫框架实现 流程_爬虫结构/原理

    目录链接:C# 爬虫框架实现 概述 首先需要讲的是,爬虫的原理.其实在我看来,爬虫只是用来解决以下四个问题的工具: 提取哪些网页 提取网页上的哪些内容 存储到哪里(推荐数据库/开源类/Console) ...

  3. Pytest系列(19)- 我们需要掌握的allure特性

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 前面我们介绍了allure的 ...

  4. Selenium系列(22) - 通过selenium控制浏览器滚动条的几种方式

    如果你还想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识, ...

  5. openswan源码ubantu下编译、安装、基本环境搭建

    openswan的编译过程 文章目录 openswan的编译过程 1. 下载源码: 2. 在虚拟机上解压后编译: 2.1 查看INSTALL文件 2.2 查看文件buildlin.sh文件 3. 查看 ...

  6. Java中使用jxl.jar将数据导出为excel文件

      Java对Excel文件的读写操作可由jxl.jar或poi.jar实现,这里使用jxl.jar完成对Excel文件的导出. 一.将Excel文件导出在本地 步骤:   创建文件 -> 创建 ...

  7. k8s 部署elasticsearch报 max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

    1.由于登不上云的节点 不采用修改节点配置的方式 修改部署的stateful 加上 initContainers 它和 containers 同一层级的 initContainers: - name: ...

  8. 彻底搞明白PHP的中引用的概念

    之前我们其实已经有过几篇文章讲过引用方面的问题,这次我们来全面的梳理一下引用在PHP到底是怎么回事,它和C中的指针有什么不同,在使用的时候要注意些什么. 什么是引用? 在 PHP 中引用意味着用不同的 ...

  9. Groovy系列(2)- Groovy与Java的不同之处

    Groovy与Java的不同之处 默认 imports 所有这些包和类都是默认导入的,不必使用显式import语句来使用它们 java.io.* java.lang.* java.math.BigDe ...

  10. CSS写一个缺角的div和菱形

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...