首页 > 其他分享 >类型限定符

类型限定符

时间:2023-03-05 23:33:05浏览次数:35  
标签:int restrict 编译器 volatile 类型 限定符

我们通常用类型和存储类别来描述一个变量。C90新增了两个属性:恒常性和易变性,这两个属性可以分别用关键字const和volatile来声明,以这两个关键字创建的类型是限定类型;C99标准新增了第三个限定符:restrict,用于提高编译器优化;C11标准新增了第四个限定符:_Atomic,C11提供一个可选库,由stdatomic.h管理,以支持并发程序设计,而_Atomic是可选支持项。C99为类型限定符增加了一个新属性:幂等,其意义是可以在一条声明中多次使用同一个限定符,多余的限定符将被忽略。

1.volatile类型限定符

volatile限定符告知计算机,代理(非变量所在的程序)可以改变变量的值。通常,它被用于硬件地址以及在其它程序或同时运行的线程中共享数据。并且volatile设计编译器的优化。

val1 = x;
/*中间是一些不涉及x的代码*/
val2 = x;

进行优化的编译器会注意到以上代码使用了两次x,但并未改变它的值。于是编译器把x的值临时存储在寄存器中,然后val2需要使用x时,才从寄存器中读取x的值,以节约时间。这个过程被称为高速缓存。高速缓存是一个不错的优化方案,但是如果一些代理再以上两条语句间改变了x的值,就不能这样进行优化了,如果没有volatile关键字,编译器会假定变量的值在使用过程中不发生改变,然后再尝试优化代码。可以同时使用volatile和const限定一个变量,通常用const把硬件时间设置为不可更改的变量,但是可以通过代理改变,这时用volatile。只能在声明时同时使用这两个限定符,顺序无关紧要。

2.restrict类型限定符

restrict关键字允许编译器优化某部分代码以更好地支持计算。它只能用于指针,表明该指针是访问数据对象的唯一且初始的方式。

int ar[10];
int * restrict restar = (int *) malloc(10 * sizeof(int));
int * par = ar;
……
for(int 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[n]改变了数据的值。如上,如果使用了restrict关键字,编译器就可以选择捷径优化计算。

restrict限定符还可用于函数形参中的指针,这意味着编译器可以假定在函数体内其他标识符不会修改该指针指向的数据,而且编译器可以尝试对其优化,使其不做别的用途。

3._Atomic类型限定符

并发程序设计把程序执行分成可以同时执行的多个线程(操作系统知识),不过多赘述。值得注意的是,要通过各种宏函数来访问原子类型;并且一个线程对一个原子类型的对象进行原子操作(原子操作即一气呵成的操作,通过关中断和开中断实现)时,其它线程不能访问该对象。

int hogs;   //普通声明
hogs = 12; //普通赋值

_Atomic int hogs; //声明一个原子类型的变量
atomic_store(&hogs, 12); //stdatomic.h中的宏,这是一个原子过程,此时其它程序不能访问hogs

4.旧关键字的新位置

C99允许把类型限定符和存储类别说明符static放在函数原型和函数头的形式参数的初始方括号中。

对于类型限定符而言,这样做为现有功能提供了一个替代的语法。根据新标准,在声明形式参数时,指针表示法和数组表示法都可以使用这两个限定符。

void fun(int * restrict a1, int * const a2, int n); //旧式语法
void fun(int a1[restrict], int a2[const], int n); //C99允许

static的情况不同,因为新的标准为static引入了一种新的与以前毫不相关语法。现在,static除了表明静态存储类别变量的作用域或链接外,新的用法告知编译器如何使用形式参数。例如,​​double stick(double ar[static 20]);​​,static的这种用法表明,函数调用中的实际参数应该是一个指向数组首元素的指针,且该数组至少有20个元素。这种用法的目的是让编译器使用这些信息优化函数的编码。


标签:int,restrict,编译器,volatile,类型,限定符
From: https://blog.51cto.com/u_15944236/6101753

相关文章

  • C语言数据类型笔记
    Unsigned如果一个字面量常数想要表达自己是unsigned,可以在后面加u或U255U用l或L表示long(long)*unsigned的初衷并非扩展数能表达的范围,而是为了做纯二进制运算,主要是......
  • 非法的时间日期类型数据
    select*fromAwhereDATE_FORMAT(START_TIME)<=CURRENT_TIMESTAMP;//查询成功select*fromAwhereDATE_FORMAT(END_TIME)<=CURRENT_TIMESTAMP;//报错,非法的时......
  • unity3D设置Target位置和怪物类型18
    设置每一组target怪物的编号TargetManager//18.设置target编号publicinttargetPosition;设置每一个怪物的编号MonsterManager//13.设置怪物的编号publ......
  • springboot中redis的基本数据类型测试
    在springboot中依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artif......
  • 类型转换异常ClassCastException
    Personp=newStudent();//父引用指向子类Students=(Student)p//向下转型,可以Teachert=(Teacher)p;//p指向的是student,而不是teacher//此时报ClassCastExc......
  • 字符串转换为基本数据类型
    字符串转换为基本数据类型Integer.parseInt();基本数据类型转为字符串String.valueOf(123);实例代码:Strings="1234";System.out.println(Integer.parseInt(s));//12......
  • Python元组类型的内置方法
    一、元组类型内置方法(tuple)元组是不可变的列表,即元组的值不可更改,因此元组一般只用于只存不取的需求。也因此元组可以被列表取代掉,所以元组相比较列表使用的很少。元组相......
  • php基本语法和数据类型、变量销毁
    1、PHP基本语法:HTML和php混合使用;一个语句以;(分号)结束;如何定义一个变量,和变量的使用;php中定义一个变量要以$符号开头:$a=34;变量的数据类型不是固定不变的,根据赋值的变化而......
  • Java基本数据类型
    整数类型:byte、short、int、longJava各整数类型有固定的表数范围和字段长度,不受具体操作系统的影响,以保证Java程序的可移植性。 说明定义long类型的变量,赋值时需要......
  • JavaScript判断变量类型的四种方法
    typeof(根据二进制判断):常用于判断基础数据类型,对于引用数据类型除了function返回‘function’,其余都返回‘object’(typeofnull===object)instanceof:主要用于区分引......