首页 > 其他分享 >C语言的5种存储类以及关键字volatile、restrict

C语言的5种存储类以及关键字volatile、restrict

时间:2023-04-25 12:06:40浏览次数:45  
标签:初始化 存储 C语言 restrict 编译器 volatile 链接 指针


《C Primer Plus》读到12章,我的C语言复习进展的挺不错。这一章介绍存储类、连接和内存管理,可以说是重中之重。
C的5种存储类:
自动——在一个代码块内(或在一个函数头部作为参量)声明的变量,无论有没有存储类修饰符auto,都属于自动存储类。该类具有自动存储时期、代码块的作用域和空链接(no linkage),如未初始化,它的值是不确定的(java要求局部变量必须初始化)

寄存器—— 在一个代码块内(或在一个函数头部作为参量)使用修饰符register声明的变量属于寄存器存储类。该类与自动存储类相似,具有自动存储时期、代码块作 用域和空连接,声明为register仅仅是一个请求,而非命令,因此变量仍然可能是普通的自动变量,但是仍然无法获取地址。。如果没有被初始化,它的值 也是未定的。

静态、空链接——在一个代码块内使用存储类修饰符static声明的局部变量属于静态空连接存储类。该类具有静态存储时期、代码块作用域和空链接,仅在编译时初始化一次。如未明确初始化,它的字节将被设定为0.

静态、外部链接——在所有函数外部定义、未使用static修饰的变量属于静态、外部链接存储类。改类具有静态存储时期、文件作用域和外部链接,仅在编译时初始化一次。如未明确初始化,它的字节也被设定为0.

静态、内部链接——与静态、外部链接存储类不同的是,它使用static声明,也定义在所有函数外部,但是具有内部链接(仅能被与它在同一个文件的函数使用),仅在编译时初始化一次。如未明确初始化,它的字节也被设定为0.

两个关键字:volatile和restrict,两者都是为了方便编译器的优化。

volatile告诉编译器该被变量除了可被程序修改意外还可能被其他代理修改,因此,当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,而不是使用寄存器中的缓存。比如
val1=x;
val2=x;
如 果没有声明volatile,系统在给val2赋值的时候可能直接从寄存器读取x(假定聪明的编译器优化了),而不是从内存的初始位置,那么在两次赋值之 间,x完全有可能被被某些编译器未知的因素更改(比如:操作系统、硬件或者其它线程等)。如果声明为volatile,编译器将不使用缓存,而是每次都从 内存重新读取x。

而restrict是c99引入的,它只可以用于限定指针,并表明指针是访问一个数据对象的唯一且初始的方式(restrict表示只能通过它限定的指针访问该指针所指向的对象。),考虑下面的例子:

int ar[10];
int * restrict restar=(int *)malloc(10*sizeof(int));
int *par=ar;

这里说明restar是访问由malloc()分配的内存的唯一且初始的方式。par就不是了。
那么:
for(n=0;n<10;n++)
{
   par[n]+=5;
   restar[n]+=5;
   ar[n]*=2;
   par[n]+=3;
   restar[n]+=3;
}


因为restar是访问分配的内存的唯一且初始的方式,那么编译器可以将上述对restar的操作进行优化:
   restar[n]+=8;

而par并不是访问数组ar的唯一方式,因此并不能进行下面的优化:
   par[n]+=8;
因为在par[n]+=3前,ar[n]*=2进行了改变。使用了关键字restric,编译器就可以放心地进行优化了。这个关键字据说来源于古老的FORTRAN。有兴趣的看看这个

 

 

restrict是C99版新增加的关键字!

如下:

C99   中新增加了   restrict   修饰的指针:   由   restrict   修饰的指针是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。对对象的存取都限定于基于由   restrict   修饰的指针表达式中。

由   restrict   修饰的指针主要用于函数形参,或指向由   malloc()   分配的内存空间。restrict   数据类型不改变程序的语义。   编译器能通过作出   restrict   修饰的指针是存取对象的唯一方法的假设,更好地优化某些类型的例程。

[典型例子]   memcpy()   在   C99   中,restrict   可明确用于   memcpy()   的原型,而在  C89 中必须进行解释。   void   *memcpy(void   *restrict   str1,   const   void   *restrict   str2,   size_t   size);   /*   通过使用   restrict   修饰   str1   和   str2   来保证它们指向不重叠的对象   */


标签:初始化,存储,C语言,restrict,编译器,volatile,链接,指针
From: https://blog.51cto.com/u_16087831/6223701

相关文章

  • C语言--扫雷
    game.h#defineROW9#defineCOL9#defineROWSROW+2#defineCOLSCOL+2#defineMINE_COUNT10//Easy#include<stdio.h>#include<stdlib.h>#include<time.h>Itals(charMxkf[ROWS][COLS],introws,intcols,charset);Print(charMxkf[......
  • C语言-----单字符输入输出
    intputchar(intc):向标准输出写一个字符,返回写了几个字符,EOF(-1)表示写失败intgetchar(void):向标准输出读入一个字符ctrl+c终止以后所有程序;Ctrl+z进入下一段程序(有点像break和continue,终止所有的和跳出)#include<stdio.h>intmain(){intch;while((ch=getchar(......
  • C语言实验报告范例
    实验报告四一,实验类型:设计型二,实验室:三,指导老师:四,日期:五,实验名称:if分支语句的嵌套六,实验目的:1,学习if嵌套结构,能够用C语言编程解决日常生活的实例2,明确if语句在实现分支结构控制语句方面的特点和优势3,熟练掌握关系运算符、关系表达式、逻辑运算符和逻辑表达式、......
  • 快速排序_C语言
    思路:base:取最低位为basej:从右向左找到比base小的数,放到第i位。i++i:从左向右找到比base大的数,放到第j位。j--当i==j时,base放到第i位,此时base左面都是小于base的,base右边都是大于base的递归:只要最低位小于最高位,执行递归代码#include<stdio.h>//作用:打印数组......
  • C语言--三子棋
    game.h#defineROW3#defineCOL3#include<stdio.h>#include<stdlib.h>#include<time.h>//声明voidDisplayboard(charboard[ROW][COL],introw,intcol);voidInitboard(charboard[ROW][COL],introw,intcol);voidplayer1(charboard[R......
  • C语言指针运算
    给一个指针加1表示要让指针指向下一个变量,也就是在地址值上加一个sizeof(指针所指的类型),例如:inta[10];int*p=a;*(p+1)=a[1];*(p+n)=====ac[n] 同理:这些指针运算可以对指针做:1.给指针加减一个整数(减就是往前移一位)2.递增递减(++/--)3.两个指针相减(其实就是两个指针的差......
  • Access restriction: The type BASE64Decoder is not accessible due to restr[转]
    在Eclipse中编写用java代码时用到了BASE64Decoder,importsun.misc.BASE64Decoder;可是Eclipse提示:Accessrestriction:ThetypeBASE64DecoderisnotaccessibleduetorestrictiononrequiredlibraryC:\Programfiles\java\jre6\lib\rt.jarAcces......
  • C语言 合并两个升序的数组,成升序的数组
    #include<stdio.h>//两路合并法把两个已按升序排列的数组合并成一个升序数组main(){inta[3]={10,13,15};intb[5]={2,4,6,7,8};intc[10],i=0,j=0,k=0;while(i<3&&j<5)if(a[i]>b[j]){c[k]=b[j];k++;j++;}else{......
  • c语言刷——滑动窗口&&双指针 leetcode合集
    目录字符串问题3.无重复字符的最长子串76.最小覆盖子串424.替换后的最长重复字符438.找到字符串中所有字母异位词1208.尽可能使字符串相等连续1的问题485.最大连续1的个数487.最大连续1的个数II(p)1004.最大连续1的个数III综合题239.滑动窗口最大值字符串问题3.无重......
  • C语言函数大全-- o 开头的函数
    C语言函数大全本篇介绍C语言函数大全--o开头的函数1.obstack_init,obstack_free,obstack_alloc,obstack_blank,obstack_grow1.1函数说明函数声明函数功能voidobstack_init(structobstack*obstack_ptr);它是POSIX标准库中的一个非标准函数,用于初始化对象堆栈。对......