引言:在内核的系统调用函数里,常常遇到函数的參数使用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. SQL注入原理及防范

    1.1.2 正文 SQL Injection:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. 具体来说,它是利用现有应用程序,将(恶 ...

  2. 在线扩展根分区 red hat 4.8.3-9

    跑程序的时候发现报错,提示空间不足,仔细查看后发现是根分区已满 27G的空间只有20k剩余 考虑从/data分区压缩一点空间到/分区 切换到root用户 执行下面的命令 1. umount /data ...

  3. Django 利用 Pagination 分页

    Django自身提供了一些类来实现管理分页,数据被分在不同的页面中,并带有“上一页/下一页”标签.这个类叫做Pagination,其定义位于 django/core/paginator.py 中. 一 ...

  4. .Net Core中的配置文件源码解析

    一.配置简述 之前在.Net Framework平台开发时,一般配置文件都是xml格式的Web.config,而需要配置其他格式的文件就需要自己去读取内容,加载配置了..而Net Core支持从命令行 ...

  5. 可能是全网最详细的express--middleware

    写在前面 hello,小伙伴们,我是你们的pubdreamcc,本篇博文出至于我的GitHub仓库node学习教程资料,欢迎小伙伴们点赞和star,你们的点赞是我持续更新的动力. GitHub仓库地址 ...

  6. CDOJ 3 BiliBili, ACFun… And More! 模拟

    原题链接:http://acm.uestc.edu.cn/#/problem/show/3 题意: 有个人在看B站视频时有个习惯,就是每当卡住的时候,他总再次从头开始看.另外,他在看视频时会先等待T的 ...

  7. Codeforces Gym - 101147J Whistle's New Car

    Discription Statements Whistle has bought a new car, which has an infinite fuel tank capacity. He di ...

  8. DNA的复制

    半保留复制 DNA分子复制时, DNA分子的双螺旋将解开, 互补的碱基之间的氢键断裂, 解开的两条单链作为复制的模板, 游离的脱氧核苷酸依据碱基互补配对的原则, 通过形成氢键结合到作为模板的单链上. ...

  9. SVG动画实践篇-字母切换

    git: https://github.com/rainnaZR/svg-animations/tree/master/src/pages/step2/letter.change 说明 这个页面实现了 ...

  10. Food hub

    Work center List Tillage 耕作 Hand harvest 手工采收 Planting 种植 Cultivating 培养 Mulching 覆盖 Dig harvest 挖地采 ...