《C Primer Plus》学习笔记之 C数据的属性(三)类型限定词

类型限定词

在ANSI C中,变量除了具有前述的四种属性(类型信息作用域链接存储时期),C90增加了两个新属性

  • 不变性(constancy),使用关键词const声明
  • 易变性(volatility),使用关键词volatile声明

这两个新属性的增加,创建了受限类型(qualified type)
C99添加了第三个类型限定词restric,用以方便编译器优化
C99规定类型限定词是幂等的(idempotent),即可以在一个生命中不止一次使用同一个限定词,多余的将被忽略掉。

类型限定词const

被const修饰的变量不能通过赋值、增量或减量运算来修改变量的值,这种变量只能在定义声明的时候进行初始化,此后变量就是一个只读变量,也可以认为是一个常量。

const double PI = 3.1415926;//PI在定义声明的时候初始化,认为是一个常量
const int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};//定义一个常量数组

const与#define的异同
(待补充)

  • 对指针使用const
    位于*左边的const使得指针指向的数据成为常量;
    位于*右边的const使得指针本身成为常量;
const float * pf;       //指针pf指向一个常量浮点数值
float const * pf;       //同上
float * const pf;       //指针pf是一个常量指针,即只能指向一个地址,但所指向的值说可以变化的
const float * const pf; //指针pf是一个常量指针,指向一个常量浮点数值,
                        //即只能指向一个地址,且所指向的存储位置的值也不能改变
  • 对函数形参使用const
    若一个函数对数组进行操作但是不改变数组的值,则函数的形参声明为const受限指针;
    若该函数需要改变数组的值,则函数形参声明为普通指针;
void show_arr(const int * ar);  //该声明表明ar指向的数据是不可变的
void show_arr(const int ar[]);  //在函数原型声明和函数头部,ar[]和*ar是相同的
void change_ar(int ar[]);       //该声明表明ar指向的数据是可变的
  • 对全局常量使用const
    使用全局变量被认为是危险的,如果是全局常量,使用const限定词,那么这种危险就不存在了。
    在文件之间共享全局常量时可以用两种方法

    1. 遵循外部变量的惯用规则:在一个文件中进行定义声明,在其他文件中进行引用声明(使用关键字extern)

      /*file1.c 定义全局常量*/
      const double PI = 3.1415926;
      const int days[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
      /*file2.c 使用在其它文件中定义的全局常量*/
      extern const double PI;
      extern const int days[12];
    2. 将全局数据放在一个头文件中,必须使用静态内部存储类

      /*constant.h 定义全局常量*/
      static const double PI = 3.1415926;
      /*file1.c 使用在头文件中定义的全局常量*/
      
      #include "constant.h"
      
      /*file2.c 使用在头文件中定义的全局常量*/
      
      #include "constant.h"
      
      • 若不使用关键词static,在文件file1.c和file2.c中包含constant.h将导致每个文件都有同一标识符的定义声明;通过定义成静态内部存储类,实际上给了每个文件一个独立的数据拷贝,由于都是常量,因此这样做并没有问题。
      • 这种方式的优点是不需要在一个文件中进行定义声明,而在另一个文件中进行引用声明,所有文件都包含一个头文件即可。缺点是复制了数据,多占用了内存,如果全局常量中包含巨大的数组,那么内存占用将会是一个问题。

类型限定词volatile

volatile告诉编译器不对变量进行优化
通常,编译器为了加速程序的执行,会对程序进行一些优化,其中的一个优化操作为:将内存变量缓存到寄存器中,当再次使用该变量时,直接存使用寄存器中的值,而不会再去内存中读取变量的值。这种优化通常是有效的,但是当一个变量会被硬件所改变或被多个并行运行的程序所共享时,在两次使用期间变量的值可能已经发生了变化,此时可以通过使用volatile关键词告诉编译器不对此变量进行此种优化。

类型限定词restrict

restrict用于方便编译器进行优化,只可用于指针,表明指针是访问一个数据对象唯一且初始的方式

int ar[10];
int * restrict restar = (int *)malloc(10*sizeof(int));
//指针restar是访问由malloc()分配的内存的唯一且初始的方式,因此可以把它限定为restrict
int * par = ar;
//指针par既不是初始的,也不是访问数组ar中元素的唯一方式,因此不能把它限定为restrict

restrict告诉编译器可以假定指针所指向的数据没有其他方式可以修改,因而可以试着对代码进行优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值