C语言中常用的一般包括const、static、extern、register和volatile这几个。这些是C语言标准中规定的关键词,所有的编译器都必须支持这些关键词,它们的作用如下:

1、const修饰的变量被称为常量,所谓常量,就是不能改变、不能再赋值的变量。

  比如int a = 10,定义了一个变量a,并初始化为a = 10,在后续的代码中我们可以随时修改a的值的,可以通过a = 15把a的值修改为15。

  但是如果使用const修饰了变量,比如const int a = 10或者int const a = 10,这时候a就是一个常量变量,它的值就固定为了初始化时的值10,后续代码如果出现了a = 15编译器就会报错告诉你a是一个常量,不能赋值。

  有一点需要注意的是cons修饰的对象,对于普通变量而言,const修饰的就是变量,但是对于指针而言,const在不同的位置修饰的对象就不同了。比如const int *p或者int const *p和int * const p修饰的就是两个不同的对象,前者const int *p修饰的是整个(*p),也         就是指针p所指向的内存中的值是常量,是不能改变的,这种称为常量指针。如果定义了const int *p = &a;int a = 10;这时候就不能再通过*p = 15来改变a的值了,但是因为a并不是const修斯的变量,我们还是可以通过给a赋值的方式修改*p的值,如果a = 15,那          么*p = 15。有一点需要注意的是,p的值是可以修改的,因为const修饰的是*p并不是p,所以我们可以通过int b = 15,p = &b的方式修改*p的值。

  这就引出了另一种修饰方式int * const p,这种称为指针常量,这时候const修饰的就是指针p,所以p的值就是不能改变的,如果有int * const p = &a,int a = 10,把么p就永远指向a所在的地址了,p = &b就是错误的。这时可以通过*p = 15和a = 15的方式修改*p的         值。

  总结下来就是常量指针 const int *p表示*p的值不能修改,但是p的值可以修改。指针常量int  * const p表示p的值是不能改变的,但是*p的值可以改变。

  使用const的本意是希望被const修饰的值不被代码其他行为修改,但是当const修饰指针的时候,如果不注意逻辑关系,往往会造成const修饰的值被意外修改:

  (1)、int a = 10;const int *p = &a,如果出现了a = 15,那么*p = 15

  (2)、const int a = 10,int b = 15,const int *p = &a,如果出现了p = &b(或者p = p1,p1为指针,*p1 = 15),那么a = 10,*p = 15

2、static可以修饰变量和函数,static修饰变量的时候分两种情况

  (1)、static修饰局部变量,自动初始化变量并延长变量的生存周期(跳出函数之后变量的值不会被释放修改),static int a;表示a是一个静态变量,并初始化为a = 0;普通的局部变量定义的时候不会初始化,它的值虽然大部分时候为0,但实际情况它可能是任                     意值(分配的地址中的值)。

  (2)、static修饰全局变量和函数,主要是限定全局变量和函数的作用域,被static修饰的全局变量和函数只能在当前源文件调用,其他源文件无法调用。

3、extern可以修饰变量和函数,它的作用申明变量和函数,告诉编译器这个变量和函数是在其他文件中定义的,要调用这个变量或者函数的时候就去其他文件查找。有一点需要注意的是,如果变量或者函数在其他文件中被static修饰了,extern就没法申明变量和函数。

4、register只能修饰局部变量,表示让编译器把这个局部变量放在寄存器当中,不要放在堆栈里,因为调用变量的时候MCU都是先把变量从堆栈中读到寄存器中再进行操作,这样直接放在寄存器中就可以节省时间。有一点需要注意,register只能修饰局部变量,因为  

  寄存器的数量是有限的,当寄存器用完了之后编译器还是会自动把变量放在堆栈区。

5、volatile可以修饰各种变量,它表示当前变量是随时可能改变的,告诉编译器调用这个变量的时候每次都去变量所在的地址读值而不是从寄存器中取值。

 

C语言中限定符的作用的更多相关文章

  1. const限定符的作用

    const限定符的作用:                                     1.定义const常量:const可以将一个对象变成一个常量,不可被修改,所以定义的 时候必须进行初始 ...

  2. C语言restrict限定符

    restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式.即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其 ...

  3. C语言中续行符“\”说明

    把一个预处理指示写成多行要用“\”续行,因为根据定义,一条预处理指示只能由一个逻辑代码行组成. 而把C代码写成多行则不必使用续行符,因为换行在C代码中只不过是一种空白字符,在做语法解析时所有空白字符都 ...

  4. Python中@修饰符的作用。

    '@'符号用作函数修饰符是python2.4新增加的功能,修饰符必须出现在函数定义前一行,不允许和函数定义在同一行.也就是说@A def f(): 是非法的. 只可以在模块或类定义层内对函数进行修饰, ...

  5. scanf函数中*修饰符的作用,如:%*d

    在scanf函数中,*修饰符可以跳过所在项的输入.如下: #include <stdio.h> int main() { ; printf("请输入:"); scanf ...

  6. printf函数中*修饰符的作用,如:%*d

    在printf函数中,我们可以用数字修饰来控制打印的字段宽度和精度,如下(为强调视觉效果,均填充0): #include <stdio.h> int main() { ; float f= ...

  7. C语言中两个!!的作用

    两个!是为了把非0值转换成1,而0值还是0. 因为C语言中,所有非0值都表示真. 所以!非0值 = 0,而!0 = 1.所以!!非0值 = 1,而!!0 = 0.例如:i=123 !i=0 !!i=1 ...

  8. OpenGL ES 2.0 限定符

    限定符 说明 作用 attribute 一般用于各个顶点各不相同的量,如顶点位置.颜色等 属性限定符,修饰的变量用来接收渲染管线传递进顶点着色器的当前顶点的各种属性值. 只能用来修饰符点数标量,浮点数 ...

  9. C语言中头文件怎么写?(本文来源网络,由黑乌鸦进一步完善)

      c语言头文件怎么写?我一直有这样的疑问,但是也一直没去问问到底咋回事:所以今天一定要把它弄明白! 其实学会写头文件之后可以为我们省去不少事情,可以避免书写大量的重复代码.有利于整理思路.使代码脉络 ...

随机推荐

  1. ps、top命令查找不到进程的解决方案

    netstat -anpt发现一个奇怪的连接,但是ps和top命令确查不到此进程,这很可能是因为因为ps和top命令被替换了导致这些进程被过滤掉了.因此我这里有个脚本专门查找出来隐藏的进程 #!/us ...

  2. C#语法糖系列 —— 第二篇:聊聊 ref,in 修饰符底层玩法

    自从 C# 7.3 放开 ref 之后,这玩法就太花哨了,也让 C# 这门语言变得越来越多范式,越来越重,这篇我们就来聊聊 ref,本质上来说 ref 的放开就是把 C/C++ 指针的那一套又拿回来了 ...

  3. 【mq】从零开始实现 mq-10-消费者拉取消息回执 pull message ack

    前景回顾 [mq]从零开始实现 mq-01-生产者.消费者启动 [mq]从零开始实现 mq-02-如何实现生产者调用消费者? [mq]从零开始实现 mq-03-引入 broker 中间人 [mq]从零 ...

  4. vue大型电商项目尚品汇(前台篇)day01

    学完vue2还是决定先做一个比较经典,也比较大的项目来练练手好一点,vue3的知识不用那么着急,先把vue2用熟练了,vue3随时都能学. 这个项目确实很经典包含了登录注册.购物车电商网站该有的都有, ...

  5. uniapp设置竖屏

    //在APP.vue中的onLaunch钩子写入plus.screen.lockOrientation('portrait-primary');

  6. Nanodet模型部署(ncnn,openvino)/YOLOX部署(TensorRT)

    Nanodet模型部署(ncnn,openvino) nanodet官方代码库nanodet 1. nanodet模型部署在openvino上 step1: 参考链接 nanodet官方demo op ...

  7. 关于基础RMQ——ST算法

    RMQ,Range Maximum/Minimum Query,顾名思义,就是询问某个区间内的最大值或最小值,今天我主要记录的是其求解方法--ST算法 相对于线段树,它的运行速度会快很多,可以做到O( ...

  8. 什么是HBase?终于有人讲明白了

    一.初识HBase HBase 是一个面向列式存储的分布式数据库,其设计思想来源于 Google 的 BigTable 论文.HBase 底层存储基于 HDFS 实现,集群的管理基于 ZooKeepe ...

  9. Java_Scanner的使用

    目录 Scanner对象 scanner.next()和scanner.nextln()的区别 scanner.hasNext()和scanner.hasNextln() Scanner拓展 视频课程 ...

  10. R数据分析:如何简洁高效地展示统计结果

    之前给大家写过一篇数据清洗的文章,解决的问题是你拿到原始数据后如何快速地对数据进行处理,处理到你基本上可以拿来分析的地步,其中介绍了如何选变量如何筛选个案,变量重新编码,如何去重,如何替换缺失值,如何 ...