专业的JAVA编程教程与资源

网站首页 > java教程 正文

c语言中那些被忽略的知识点,但效果奇佳,肯定有你忽略的(续)

temp10 2024-11-05 11:53:43 java教程 14 ℃ 0 评论

昨天主要讲了c语言中被忽略的知识点《断言》。其中感谢读者给我的批评意见,秉着代码是严谨的原则,在今天的正文开始前,对昨天的疏忽在此纠正一下:

第一:感谢读者@FreedomZSX 的指正,昨天我提到assert是关键字,该说法是错误的,在c语言里只是一个宏,甚至也不是一个函数。之前写java习惯了,在java里面assert被称为关键字。

c语言中那些被忽略的知识点,但效果奇佳,肯定有你忽略的(续)

第二:有读者说,直接在c文件里直接使用断言会编译不通过,我想说,我帮你验证了,并且通过了,达到了assert的效果。环境Visual Studio 2012.

第三:断言确实可以指出错误所在,但是没经过改写的断言提示的错误是一大堆,这个是我的疏忽,没有及时验证。我们公司使用的断言都是经过改写的,所以可以直指错误的地方,而不是报类似下面的错误。不过我觉得这个错误提示也应该很明显了。

好了,开始今天的正文,今天主要聊类型限定词。

类型限定词:const,volatile,restrict

1.const相信都已经很熟悉了,这个也是使用次数最多的。简要回顾一下,如果变量声明中带有关键字const,则不能通过赋值、增减量运算来修改该变量的值,否则编译器会报错。不过,还是要适当注意书写,如下:(关于const和指针变量的使用,在后续指针部分会详细说明)

2.volatile,限定词volatile告诉编译器,该变量除了可被程序改变以外还可以被其他代理改变。典型的,被用于硬件地址和与其他并行运行的程序共享的数据。举个例子,一个地址中可能保存着当前的时钟时间,不管程序做些什么,该地址的值都会随着时间而改变;同理,一个地址被用来接受来自于计算机的消息。

需要再强调的是,当要求使用volatile的变量值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该出读取过数据。在细说就是,遇到这个关键字的变量,编译器不在对该变量的代码进行优化,从而可以保证对特殊地址的稳定访问。

当然了,volatile和const可以同时使用,比如,硬件时钟一般设定为不能为程序所修改,但可以被程序以外的代理改变,前者就需要const限定,后者就可以加上volatile。只需要对变量声明这两个限定词就好了,顺序无所谓。

3.restrict,restrict通过允许编译器优化某几行代码增强了计算支持。只可适用于指针,并表明指针是访问数据的唯一且初始的方式。restrict是c99标准引入的。

在c库中有两个函数,都可以把一个位置把字节复制到另一个位置,在c99下,标准如下:

函数功能相同,都是把s2指向的位置复制n字节数据到s1的位置,并且均返回s1指向的位置。二者间的差别由关键字restrict造成,memcpy可以假定两个内存区域没有重叠,memove则不做这个假定。因此,复制过程类似于,首先将所有字节复制到一个临时缓冲区,然后在复制到最终目的地。如果两个区域存在重叠,在使用memcpy,就会造成不可预知的错误,即使可以正常工作,潜在的危险也是很大的。所以,在使用memcpy时,程序员必须保证区域没有重叠,使用memove则不会。

最后需要说明的是,关键字restrict有两个读者,一个是编译器,他告诉编译器可以自由的做一些有关优化的设定,另一个读者是用户,告诉用户仅适用满足restrict要求的参数。一般来说,编译器无法检查您是否遵循了这一限制,如果你忽视了它,就是在给自己挖坑了。

每天进步一点点,每天消化一点点。如果文章对你有帮助,我就觉得很值了,如果你有更好的意见,欢迎一起交流。后续我会继续更新。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表