引言:在内核的系统调用函数里,常常遇到函数的參数使用restrict限定词限定的情况,以下就对该关键词做个总结。

1、restrict关键词是C99特性才加入的,因此在编译使用含有该限定词的程序时,一定要在后边加入-std=c99的标志,使得gcc能够支持c99标准。

2、restrict既然是个限定词。那么它限定什么变量呢?它仅仅能限定指针变量。经过它限定的数据对象,表明指针时訪问该数据对象的唯一且初始的方式。注意:这里的唯一表明了,由它限定的指针所指向的数据块。仅仅能由该指针訪问,不能由除它之外的不论什么方式訪问。初始指的是它必须在初始化的时候声明,不能再以后声明。后面给出样例解释。

3、restrict事实上能够看成仅仅有两个读者。一个是编译器,它告诉编译器能够自由地做一些有关优化的假定。

还有一个读者是用户,它告诉用户仅适用满足restrict要求的參数。比方,下列两个函数声明:

void *memcpy(void *restrict s1, const void *restrict s2, size_t n);

void *memmove(void *s1, const void *s2, size_t n);

上面两个函数都是从位置s2把n个字节拷贝到位置s1。

函数memcpy()要求两个位置之间不重叠。但memmove()没有这个要求。

把s1和s2声明为restrict意味着每一个指针都是对应数据的唯一訪问方式,因此他们不能訪问同一数据块。这满足了不能有重叠的要求。

程序演示样例restrict.c:

#include <stdio.h>
#include <stdlib.h> int
main(int argc, char **argv)
{
int n;
int ar[5];
int *restrict restar = (int *)malloc(5 * sizeof(int));/*将该指针声明为了restrict。使得这块内存的数据仅仅能由restar訪问,不能由以下的par指针訪问*/
int *par = ar; for(n = 0; n < 5; n++){
par[n] += 5;
restar[n] += 5;
ar[n] *= 2;
par[n] += 3;
restar[n] += 3;
printf("ar[%d] = %d\n", n, restar[n]);
printf("ar[%d] = %d\n", n, ar[n]);
} return -1;
}

编译:gcc restrict.c -std=c99

运行编译结果:./a.out

ar[0] = 8
ar[0] = 4851221
ar[1] = 8
ar[1] = 4849653
ar[2] = 8
ar[2] = 269027981
ar[3] = 8
ar[3] = 2147391485
ar[4] = 8
ar[4] = 2614935

从结果能够看出,通过par指针以及ar所訪问的restar指针所指向的数据并没有起不论什么作用。

能够改变所指向内存数据的仅仅是restar[n] += 5;与 resatr[n] += 3;这两条语句。事实上编译器会对这两条语句做优化,将它们合并成一条语句:restar[n] += 8;

【C语言天天练(十九)】restrict关键词的更多相关文章

  1. 【C语言天天练(九)】动态内存分配

    引言:数组的元素存储于内存中连续的位置上.当一个数组被声明时.它所须要的内存在编译时就被分配. 可是,我们能够使用动态内存分配在执行时为它分配内存. 一块内存的生命周期能够分为四个阶段:分配.初始化. ...

  2. 【C语言天天练(十五)】字符串输入函数fgets、gets和scanf

    引言:假设想把一个字符串读到程序中.必须首先预留存储字符串的空间.然后使用输入函数来获取这个字符串. 读取字符串输入的第一件事是建立一个空间以存放读入的字符串. char *name; scanf(& ...

  3. 【C语言天天练(十)】结构体

    引言:数据常常以成组的形式存在.在C中,使用结构能够把不同类型的值存放在一起. 结构的声明有两种 1.struct SIMPLE{ int a; char b; float c; };然后用标签SIM ...

  4. 数据结构算法C语言实现(十九)--- 5.5&5.6&5.7广义表

    一.简述 传说Lisp的基本数据结构就是广义表,广义表也是具有典型递归属性的数据结构,此外,由于建表要处理字符串,用C语言处理起来也是一脸懵逼.....最后自己还想写一个将广义表还原成字符串的函数,一 ...

  5. 【C语言天天练(二一)】内联函数

            引言:调用函数时,一般会由于建立调用.传递參数.跳转到函数代码并返回等花费掉一些时间,C语言的解决的方法是使用类函数宏.在C99中,还提出了第二种方法:内联函数.         内联 ...

  6. 【C语言天天练(二四)】内存分配

    引言: 对于C语言程序,了解它执行时在内存中是怎样分配的对于我们理解它的执行机制是很实用的.以下就总结一下C语言程序的一些内存分配知识. 一 一段C程序.编译连接后形成的可运行文件一般有代码段.数据段 ...

  7. 【C语言天天练(二)】预处理

    引言: 学C语言之初.一提到预处理,脑子里想到的就是#define的宏定义以及#include包括的头文件.后来随着对C的深入学习发现.预处理不止这些.比方条件编译.提前定义的宏等等.以下对此进行总结 ...

  8. 【C语言天天练(十一)】深入理解指针

    引言:在C语言中.指针的地位是不言而喻的,要想非常好的掌握C语言,掌握指针是必须的,这也是C语言不同于其它语言的地方. (一)指针的指针 样例: int i; int *pi;/*把pi初始化为指向变 ...

  9. Swift5.1 语言指南(二十九)高级运算符

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

随机推荐

  1. C、C++变量auto,static,register,extern类型

    auto: 推导类型变量:编译器选项指示编译器如何使用 auto 关键字来声明变量. 如果指定默认选项 /Zc:auto,编译器从其初始化表达式中推导声明的变量的类型. 如果指定 /Zc:auto-, ...

  2. react状态

    组件的生命周期分成三个状态: Mounting:已插入真实 DOM Updating:正在被重新渲染 Unmounting:已移出真实 DOM React 为每个状态都提供了两种处理函数,will 函 ...

  3. AC日记——花店橱窗布置 codevs 1028

    题目描述 Description 假设以最美观的方式布置花店的橱窗,有F束花,V个花瓶,我们用美学值(一个整数)表示每束花放入每个花瓶所产生的美学效果.为了取得最佳的美学效果,必须使花的摆放取得最大的 ...

  4. 快速上手 Echarts

    最近使用到了 百度的 Echarts 数据可视化工具,这里简单介绍如何快速上手. 一.下载 这里选择目前最新版本,4.2.1 地址:https://github.com/apache/incubato ...

  5. Linux字符模式下如何设置/删除环境变量

    Linux字符模式下设置/删除环境变量方法: bash下 设置:export 变量名=变量值 删除:unset 变量名 csh下 设置:setenv 变量名 变量值 删除:unsetenv 变量名 h ...

  6. android 获取GPS定位

    AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xm ...

  7. [置顶] Android 应用内禁止截屏功能的实现

    截图介绍   Android的调试工具DDMS提供有截屏功能,很多软件也会有截屏功能,在做支付等安全类应用的时候,为了保证用户的资产和系统安全,往往会禁止应用内截屏,禁止之后,在此应用处于前台的情况下 ...

  8. 为什么HierachyViewer无法连接真机调试

    关于什么是Hierarchy Viewer,请查看官方文档:http://developer.android.com/tools/debugging/debugging-ui.html.个人理解:Hi ...

  9. GOF23种设计模式-工厂模式

    • 工厂模式: – 实现了创建者和调用者的分离. – 详细分类: • 简单工厂模式 • 工厂方法模式 • 抽象工厂模式 • 面向对象设计的基本原则: – OCP(开闭原则,Open-Closed Pr ...

  10. lstm作的第一首诗,纪念

    黄獐春风见破黛,十道奇昌犹自劳. 开领秦都色偏早,未知长柳是来恩. 争时欲下花木湿,早打红筵枝上香. 酣质矫胶麦已暮,丝窗瑞佩满含龙. 感觉有点意思哈,花木对应枝上,还有点对仗的意味. 于是接着又弄了 ...