首页 > 作文

深入聊聊C语言中的Const关键字

更新时间:2023-04-04 22:38:43 阅读: 评论:0

目录
前言01const简述02常量的应用常量作为函数的参数c++中应用加const03#define和const总结

前言

const是一个c语言的关键字,它限定一个变量不允许被改变。使用const在一定程序上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解别人的程序有所帮助。

01const简述

下面简单描述一下const,基本都是教科书的知识。const修饰的变量,其值存放在只读数据段中,其值不能被改变。称为只读变量。关于什么是数据段,什么是代码段,请看我之前的文章《c细口瓶语言的内存分配》。

int const a;const int a;

上面两条语句都可以将a声明为一个整数,它的值不能被修改。这两种方式你可以任意选一种即可。

常量在定义时可以被初始化。

int const a =15;

当指针和常量结合时,就会很有趣,因为有两样东西都可能成为常量,指针和它指向的实体。一般大家在大学考计算机二级和面试时经常会遇到的。

int *a;

a就是一个很普通的指向整型的指针。

int const *a;

这时则是一个指向整型常量的指针。也就是说,你可以修改指针的值,但是不能修改它指向的值。

int *const a;

这时a是一个指向整型的常量指针。这个指针是常量,它的值无法修改,但是你可以修改它所指向的整型的值。

int const *const a;

这个时候无论是指针本身还是它所指向的值都是常量,都不允许修改。

那么问题来了,就像c语言的运算符的优先级,这个东西很不好记忆,在实际开发中,我们直接多用()符号解决优先级的问题。上面指针和const结合那么麻烦,学习为了什么呢?

1、合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

2、正是基于上面的原因,一些优秀的开源代码都会利用const这个属性,深入理解后,方便我们阅读理解一些优秀的开源代码。

02常量的应用

上文就简述了一下教科书中的const定义,现在说一下const在我日常开发中的应用。

在单片机开发中

const定义一个常量,在单片机开发中,一个定义在函数体外的常量constint a = 5; 它是存储在单片机内部flash里的,不懂的同学请看之前的文章《c语言在stm32中的内存分配》。那么上文提到和指针结合时,也是存储在内部flash中吗?我们来验证一下

int data上枢密韩太尉书 = 0x1234;int const *a = &data;int *const b= &data;int const *const 关于时间的诗句c= &data;int main(void){    int data1 = 0x1234;    a =&data1;    data1 = *b;    data1 = *c;    while(1);}

它们的内存分配如下

b和c是分配到内部flash的,a是分配到ram中的。其实这也很好理解,根据上面的const的定义,单片机在分配时,将不能修改的变量,也就是只读变量放到flash中,可以读写的变量放到ram中,这个大家仔细想一下就明白了。

常量作为函数的参数

非指针参数(也就是传值参数)不会被修改原始值,const对它是没有意义的,所以这里只讨论参数是指针加const的情况。

在上面看到,指针加const共3种情况,这里先讨论int const *a; 也就是你可以修改指针的值,但是不能修改它指向的值。

int fun(int *p) {      if(*p == 0xa5)      {            return*p;      }el{             p++;            return *p;      }}

上面是个简单的例子,也就是传入一个指针,函数读取指针指向的内容,执行不同的命令。类似串口接收,一个函数内部处理这些数据,但是不能修改,可能串口接收的数据在其他地方还有用。

在上述例子中,没有问题的,因为代码全在“掌控”中。函数内部是否进行写操作,自己是知道的。但还有一个更规范的写法。

int fun(int const *p) {      if(*p == 0xa5)      {            return *p;     }el{             p++;             return *p;      }}

这里写法,就是明显表现出自己的设计意图,函数内部不可以对指针指向的内容进行修改,只能读取。

如果尝试修改,编译器会直接报错的。但是函数内部也是可以绕过去,修改的数据的,如下

int fun(co居安思危nst int *p) {     int *p2 = p; /* 来个重名指针会绕过const的限制*/     *p2 += 1;      return*p;}

那么对于int *const a;有没有对应的使用场景呢?如下

这样的接口设计,如果函数内部尝试修改指针的值,也就是指针指向的位置,编译器就会直接报错。

不过这里例子很现实,因为即使去掉p2的const修饰,编译器会直接报waring,因为p2是入参。这里只是简单举例子,大家理解意思就好。

在日常开发中,入参是intconst *a; 使用场景比较多。

c++中应用加const

c++中可以使用应用的语法,这里不再展开什么是应用,如下例子,c++函数参数中引用时也常加const修饰,如下

void find(constint  &x){     .......}

最后,举两个常用的标准c库函数声明,它们都是使用const的典范。

1.字符串拷贝函数:char*strcpy(char*strdest,constchar *strsrc);

2.返回字符串长度函数:intstrlen(constchar *str);

03#define和const

#define预编译和const在某些情况下有些“混淆”,如下

#define max_num 5int const max_num = 5;void fun(){      if(len >max_num)      if(len> max_num)}

上述代码5行和6行都能起效果。那么我们就详细分析一下它们的区别

1、#define的数据是宏定义,它占用的是代码段空间(单片机对应:内部flash),const定义一个数据类型,它占用的是data段(单片机对应:内部ram)。

2、如上,#define是宏定义,在预编译阶段直接替换,而const是数据类型。

#define max_num 5int const max_num = 5;int data[max_num];intdata2[max_num];

上述代码第4行是编译不过的,因为max_num是一个int的数据类型变量,数组定义的长度不能用变量。实际上,在更章节第一个例子,只用于判断长度,#define更加合适,因为只要允许使用字面值常量的地方都可以使用宏定义。

3、define只是简单的字符串替换,没有类型检查。而const有对应的数据类型,是要进行判断的,可以避免一些低级的错误。define只是简单的字符串替换会导致边界效应,

比如定义

#define a 1#define b a+3#define c a/b3

那么c是多少呢?c=a/b3=a/a+33=1/1+33=10;所以这种用的时候可以直接都用个括号括起来,就诗词起名不怕边界效应了。

4、const不能重定义,不可以定义两个一样的,而define就比较牛气了,它通过undef取消某个符号的定义,再重新定义。并还可以用于判断宏定义是否存在,常用于头文件防止头文件被重复引用。

#ifndef graphics_h //防止graphics.h被重复引用 #definegraphics_h    ……代码…… #endif

5、const常量可以进行调试的,define是不能进行调试的,主要是预编译阶段就已经替换掉了,调试的时候就没它了。

总结

到此这篇关于c语言中const关键字的文章就介绍到这了,更多相关c语言的const关键字内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 22:38:42,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/6034d21f19cd3534b61718cfc5b9999a.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:深入聊聊C语言中的Const关键字.doc

本文 PDF 下载地址:深入聊聊C语言中的Const关键字.pdf

标签:指针   常量   定义   函数
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图