前言

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

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

练习题

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

  • 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. Linux高级之语句表达式

    表达式 表达式和语句是 C 语言中的基础概念.什么是表达式呢?表达式就是由一系列操作符和操作数构成的式子.操作符可以是 C 语言标准规定的各种算术运算符.逻辑运算符.赋值运算符.比较运算符等.操作数可 ...

  2. Vite详解

    vite 目录 一.推荐两个插件插件 Volar Vue 3 Snippets 二.vite简介 优势分析 浏览器支持 三.vite搭建vue3.x项目 1.创建项目 2.集成Vue-Router 3 ...

  3. elementui table的新增,编辑和删除

    \ 新增 this.tableData.unshift(data); 编辑 this.$set(this.tableData,data.index,data); 删除 rows.splice(inde ...

  4. CodeForce-782B The Meeting Place Cannot Be Changed(高精度二分)

    https://vjudge.net/problem/CodeForces-782B B. The Meeting Place Cannot Be Changed time limit per tes ...

  5. minix3使用轻快入门

    minix3是一款迷你的unix作业系统,但又不在at&t代码的基础上构建.当年开发这款作业系统的作者仅仅是拿来自用,给学生上课使用的. 如果你已经安装了minix3,你还需要安装openss ...

  6. 记一次k8s pod频繁重启的优化之旅

    关键词:k8s.jvm.高可用 1.背景 最近有运维反馈某个微服务频繁重启,客户映像特别不好,需要我们尽快看一下. 听他说完我立马到监控平台去看这个服务的运行情况,确实重启了很多次.对于技术人员来说, ...

  7. Jmeter扩展组件开发(7) - 自定义java请求的开发

    CODE package com.demo;import org.apache.jmeter.config.Arguments;import org.apache.jmeter.protocol.ja ...

  8. MYSQL分页 limit 太慢优化

    limit分页原理 当我们翻到最后几页时,查询的sql通常是:select * from table where column=xxx order by xxx limit 1000000,20.查询 ...

  9. Composer基础

    摘要 本文介绍Composer的入门知识,包括require和autoload部分. Java有Maven, Node.js有npm, ROR有gem, 这些语言的程序员在开心地使用包管理工具加速开发 ...

  10. PolarDB PostgreSQL Buffer Management 原理

    背景介绍 传统数据库的主备架构,主备有各自的存储,备节点回放WAL日志并读写自己的存储,主备节点在存储层没有耦合.PolarDB的实现是基于共享存储的一写多读架构,主备使用共享存储中的一份数据.读写节 ...