C语言之存储类的相关的关键字

不同的数据在内存中的存储位置是不同的,总体来说内存中存储数据的地方主要有四部分:栈、堆、数据段、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来禁止这些优化。

对于volatile关键字的描述主要来自于下面的博客

http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html

7:restrict

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

http://blog.chinaunix.net/uid-22197900-id-359209.html

时间: 2024-11-05 01:08:08

C语言之存储类的相关的关键字的相关文章

4.7 C语言的存储类,作用域,生命周期,链接属性

C语言背后的运行机制,学会了会对C语言更加熟悉,可以直接看到C语言的骨头里去. 存储类(storage class): ①什么是存储类? 存储类就是变量存储类型,即变量在内存中存储在什么段. 例如:栈:普通局部变量. 数据段(.data):初始化不为零的全局变量,静态局部变量. bss段:初始化为零 或 未初始化的全局变量. (其实bss段就是初始化为0的数据段)   代码段(.text):存放程序执行代码的一块内存区域. ②存储类相关的关键字? auto static register ext

C语言的存储类

Auto  普通局部栈变量:是自动存储,限定变量只能在函数内部使用,这种对象会自动创建和销毁 ,建议这个变量要放在堆栈上面,调用函数时分配内存,函数结束时释放内存.一般隐藏auto默认为自动存储类别.我们程序都变量大多是自动变量. 实例 auto.c 1 #include <stdio.h> 2 3 int main(void) 4 { 5 auto int i = 9; /* 声明局部变量的关键字是 auto; 因可以省略, 几乎没人使用 */ 6 printf("%d\n&quo

C语言笔记之存储类

在C语言中,一个数据对象(往往是指变量)可以由3种属性来描述:作用域,存储时期,链接.每种属性有不同的值,这些不同值的组合构成数据对象的存储模型,又称为存储类,即,一个数据对象如何存在于计算机中.以下描述中,我们以变量为例(另一个例子是函数)代表数据对象. 一.作用域 作用域属性描述了一个数据对象可以在(源代码的)哪些区域被访问,它有以下几个值:代码块.函数原型.文件. 1.文件作用域 函数是C源代码文件的基本组织单位,但是如果一个变量定义在所有函数之外,即没有在任何一个函数体内,那么该变量就具

C语言--存储类、链接和内存管理

注:此文为<C Primer Plus>一书中的部分总结,写下来方便以后参考. 用于存储程序数据的内存可用存储时期.作用域和链接来表征. 存储时期可以使静态的.自动的或者分配的.①如果是静态的,内存在程序开始执行时被分配,并行程序运行时一直存在.②如果是自动的,变量所用内存在程序执行到该变量定义所在代码块时开始分配,在退出代码块时释放.③如果是分配的内存,内存通过调用malloc()(或其他相关函数)分配,通过调用函数free()释放. 作用域决定哪一部分程序可以访问某个数据.在所有函数之外定

c语言中用户标识符的作用域和存储类(2)

2 局部变量及其作用域和生存期 2.1 auto变量 当在函数内部或复合语句内定义变量时,如果没有指定存储类,或使用auto说明符,系统默认所定义的变量为自动类别.因此: float a; 等价于 auto float a; auto变量的存储单元被分配在内存的动态存储区.当进入函数体时,系统自动为auto变量分配存储单元:退出时自动释放这些存储单元.这类局部变量的作用域是从定义的位置起,到函数体结束为止.由于函数的频繁调用,动态存储区内为某个变量分配的存储单元位置随程序的运行而改变,变量的初值

C语言学习系列(六)存储类

一.C存储类 存储类定义C程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在他们所修饰的类型之前.for example:auto.register.static.extern. (一).auto存储类 auto存储类是所有局部变量的默认存储类. { int mount; auto int month; } 上面的实例定义了两个带有相同存储类的变量,auto 只能用在函数内,即 auto 只能修饰局部变量. (二).register存储类 register存储类用于定义存储在寄存器而不

存储类、作用域、生命周期、链接属性

1.linux下C语言程序的内存映像代码段(.text).数据段(.data).bss段.栈.堆的概念 代码段(.text) (1)对应着程序中的代码(函数),代码段在linux中又叫文本段(.text)(2)部分平台下的const修饰的变量. 数据段(.data) 1.显式初始化为非0的全局变量: 2.显式初始化为非0的static局部变量 bss段 1.显式初始化为0或者未显式初始化的全局变量: 2.显式初始化为0或未显式初始化的static局部变量. 栈 局部变量分配在栈上:函数调用传参过

7、C_存储类 &amp;amp; 作用域 &amp;amp; 生命周期 &amp;amp; 链接属性

概念解析 存储类 存储类就是存储类型,也就是描述C语言变量在何种地方存储. 内存有多种管理方法:栈.堆.数据段.bss段..text段······一个变量的存储类属性就是描述这个变量存储在何种内存段中. 譬如:局部变量分配在栈上,所以它的存储类就是栈:显式初始化为非0的全局变量分配在数据段,显式初始化为0和没有显示初始化(默认为0)的全局变量分配在bss段. 作用域 作用域是描述这个变量起作用的代码范围. 基本来说,C语言变量的作用域规则是代码块作用域.意思就是这个变量起作用的范围是当前的代码块

ISO/IEC 9899:2011 条款6.7.1——存储类说明符

6.7.1 存储类说明符 语法 1.storage-class-specifier: typedef extern static _Thread_local auto register 约束 2.在一个声明中,在声明说明符中最多只能给出一个存储类说明符,除了_Thread_local可以与static或extern一起出现.[注:见“未来语言方向”(6.11.5)] 3.在含有语句块作用域的一个对象的声明中,如果声明说明符包含了_Thread_local,那么它们应该也包含static或是ext