首页 未命名正文

linux编程_C语言之存储类的相关的关键字

云返利网 未命名 2020-05-26 09:06:24 26 0

差别的数据在内存中的存储位置是差别的,总体来说内存中存储数据的地方主要有四部门:栈、堆、数据段、bss段,这些地方划分存放着差别的数据,好比栈一样平常用来存储局部变量,堆内存需要程序员字自己申请以及释放,主要用来存放对照大的数据;数据段主要用来存放显示初始化的全局变量和static关键字修饰的静态局部变量;bss段一样平常用来存放未显式初始化的全局变量或显式初始化为0的全局变量(C语言中,默认全局变量初始化为0)。C语言还提供了一些关键字来修饰变量,使其附有其他的属性,这些关键字主要有:auto、static、const、register、extern、volatile、restrict。

1:auto

  auto关键字的作用只有一个:修饰局部变量,auto关键字修饰后的局部变量示意是自动局部变量,自动局部变量是分配在栈上面的,C语言中默认局部变量就是自动局部变量。

2:static

  static关键字的作用有两种:

  第一种:修饰局部变量,获得静态局部变量,静态局部变量是被分配在数据段或者bss段上面的,而非静态局部变量是被分配在栈上面的。

  第二种:修饰全局变量,获得静态全局变量,静态全局变量和非静态全局变量的对照如下:

(1)静态全局变量和全局变量的存储类一样,都是被分配在数据段或者bss段

(2)静态全局变量和全局变量的生命周期一样,

(3)静态局部变量的作用域是代码块作用域({}:为一个代码块,通俗局部变量一

样),链接属性是无毗邻;全局变量的作用域是文件作用域(和函数一样),链接属性是外毗邻。

3:const

  const常被称为常量修饰符,也就是说const修饰后的“变量”变成了常量,(以是在函数传参时常用const来修饰输入型参数,不用const修饰的参数我们常以为是输出型参数。)然则在C语言中,这种常量也不算是完全不可变的,由于const修饰后的“变量”并不是被放到代码段(代码段是只读的,数据被放到代码段就无法修改),const关键字修饰的“变量”通过指针的方式照样可以修改的,详细实现是通过指针指向这个“变量”,然后解引用就可以修改const修饰后的“变量”。

4:register

 register关键字不常用,它的作用也是唯一的:register修饰的变量,将来在编译的时刻编译器会只管将它分配到寄存器中(平时一样平常的变量都是被分配到内存中的),变量被分配到寄存器中其使用和被分配到内存中是一样的,然则其速写的效率会高许多。然则由于寄存器的数目是有限的,以是这里只是只管放到寄存器中,而不是一定。我们平时需要用register修饰的变量很少,以是需要慎用。

5:extern

  extern关键字是用来声明全局变量的,原因是C语言中编译的时刻是以单个.c文件为单元来举行编译的,然则一个大的工程中不可能只有一个.c文件,这个时刻就需要extern将变量,函数等声明要.c文件外部,这样编译的时刻a.c中的函数和变量就可以被b.c所挪用。

6:volatile

 volatile修饰的变量示意这个变量随时可以被修改,因此编译后的程序每次需要存储或者读取这个变量时都市直接从变量地址中去读取数据,而没有volatile修饰的变量,则编译器可能会优化读取和存储,可能暂时使用的就是寄存器中的值,若是这个变量被其他程序修改了的话,编译器就有可能以为这个变量仍然没有被修改(原因是读取的可能是寄存器内里的谁人副的变量值,而程序修改的是内存中变量的值)

int flag; 

void test(void)

{   

    do1();

    while(flag==0);

    do2();

}

只有当flag不为0时,d02()函数才气被被执行,假设现在我们通过按下按键来发生中止,然后再中止处置函数中将flag赋值为1,这样d02()函数就能被执行了,然则编译器并不知道flag的值被其他程序所修改了,原因是编译器在编译的时刻会对程序举行优化,这样的优化会可能会将flag放入寄存器,下次读取的时刻就可能的是寄存器中的flag的谁人值。

一样平常来说,volatile主要用在下面几个地方

(1)中止服务程序中修改的供其他程序检测的变量

(2)多义务环境下各义务间共享的标志应该加volatile

(3)存储器映射的硬件寄存器通常也要加volatile举行说明,由于每次对他们的读写可能差别。

简朴来说,volatile总是和优化有关,编译器有一种手艺叫做数据流剖析,剖析程序中的变量在哪赋值、在哪使用、在哪失效,剖析效果可以用于常量合并,常量流传优化,进一步可以死代码消除,然则有时刻程序不需要这些优化,这时刻就可以通过volatile来克制这些优化。

7:restrict

restrict关键字只能用来修饰指针,不能用来修饰变量,详细用法可参照下文

c99中新增加了一个类型界说,就是restrict。

看了下网上的相关贴子,但照样问题解决的不够。下面是相关一个文章,我将在后面再加相关说明:
那么restrict的意义是什么呢?

归纳综合的说,关键字restrict只用于限制指针;该关键字用于见告编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它举行修改操作的途径;这样的结果是辅助编译器举行更好的代码优化,天生更有效率的汇编代码。

举个简朴的例子

int foo (int* x, int* y)
...{
*x = 0;
*y = 1;
return *x;
}

很显然函数foo()的返回值是0,除非参数x和y的值相同。可以想象,99%的情况下该函数都市返回0而不是1。然而编译起必须保证天生100%准确的代码,因此,编译器不能将原有代码替换成下面的更优版本

int f (int* x, int* y)
...{
*x = 0;
*y = 1;
return 0;
}

啊哈,现在我们有了restrict这个关键字,就可以利用它来辅助编译器平安的举行代码优化了

int f (int *restrict x, int *restrict y)
...{
*x = 0;
*y = 1;
return *x;
}

此时,由于指针 x 是修改 *x的唯一途径,编译起可以确认 “*y=1; ”这行代码不会修改 *x的内容,因此可以平安的优化为

int f (int *restrict x, int *restrict y)
...{
*x = 0;
*y = 1;
return 0;
}

最后注重一点,restrict是C99中界说的关键字,C++现在并未引入;在GCC可通过使用参数" -std=c99"
来开启对C99的支持

【关于云返利网】

云返利网是阿里云、腾讯云、华为云产品推广返利平台,在各个品牌云产品官网优惠活动之外,云返利网还提供返利。您可以无门槛获得阿里云、华为云、腾讯云所有产品返利,在官网下单后就可以领取,无论是自己用、公司用还是帮客户采购,您个人都可以获得返利。云返利网的目标是让返利更多、更快、更简单!详情咨询13121395187(微信同号)