C语言_了解一下C语言中的四种存储类别
C语言是一门通用计算机编程语言,应用广泛。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
C语言中的四种存储类别:auto(自动的)、static(静态的)、register(寄存器的)、extern(外部的)
1、auto(自动的)
例:auto int a;定义的整形变量a的存储方式是自动存储的,也就是说动态的分配存储空间和释放存储空间。比如说,在一个调用函数里定义的变量,当我们调用这个函数时,CPU在动态存储区分配一个存储空间,这个存储空间用来放变量a的值,当调用函数执行完之后,CPU会释放这个存储空间(也可以这样理解,之前定义a时,CPU把一个存储空间给了a,a对这个存储空间有了使用权,其他的人无法去占用这个存储空间,当CPU释放这个存储空间时,也就意味着这个存储空间是无主的,其他的人可以占用它)。还有需要注意的是,当我们再次调用这个函数时,CPU分配的存储空间的地址并不一定是之前的地址,也就有了这样的一种情况,当我们定义一个变量时,不给它初始值,它的值是不确定的。
我们之前编写程序的时候很少用到auto定义变量,其实我们之前定义的变量前面没有加static,编译系统会默认为是auto的存储方式,都会把变量存放在动态存储区。
例如:
int f(int a) /*定义 f 函数,a 为参数*/
{auto int b,c=; /*定义 b,c 自动变量*/
……
}
a 是形参,b,c 是自动变量,对 c 赋初值 3。执行完 f 函数后,自动释放 a,b,c 所占的存储单元。
关键字 auto 可以省略,auto 不写则隐含定为“自动存储类别”,属于动态存储方式。
2、static(静态的)
例:static int a;定义的整形变量a的存储方式是静态存储的,静态局部变量是放在静态存储区内分配存储单元的,在整个程序运行期间都不释放,跟全局变量一样长期占用内存。但是静态变量和全局变量还是不一样的,比如说,静态变量只能在所定义的函数内引用,静态局部变量在函数调用结束后是仍然存在的,但不能被其他函数引用。
静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已经有了初值,以后每次调用函数时不再对其重新复制,而只是保留上次函数调用结束时的值。在定义静态局部变量时,如不赋初值,则编译时自动赋初值为0。
有时在程序设计中定义一个全局变量,只限于被所在源文件引用,而不想让其他文件引用,则可在定义全局变量前面加static。
3、register(寄存器的)
对于一些频繁使用的变量,程序在执行的过程中,每次用到这些变量的时候,都要从内存取出来,运算完了之后还要写到内存中去,循环执行的次数越多,花费的时间就越多,为提高效率,C++允许将局部变量放在CPU的寄存器上,需要用到时直接从寄存器上取出参加运算,就不用再到内存中取;
例:register int i,sum=0;
for(i=;i<;i++)
sum+=i;
i和sum都是频繁使用的变量,所以将他们定义为寄存器变量。
当今的优化编译系统能够识别使用频繁的变量,从而自动将这些变量放在寄存器中,而不需要设定为register。因此,用register声明变量是不必要的。
4、extern(外部的)
要理解extern的作用,前提要对全局变量有所了解。
全局变量的作用域只限于从定义那一行开始,到文件最后一行,终究只限于所在源文件中。如若想在其他源文件引用其他源文件的全局变量,则要在其他源文件声明该变量是extern的(来自外部的,其他源文件的),这样扩大了全局变量的作用域。
例:char flag=1;
extern char falg;
赋初值是在定义时进行,外部变量声明不能赋初值,不能更改。
以上内容摘自[百度百科]
下面来个实际例子来测试下普通变量和静态变量
fileOne.h头文件如下:
#ifndef DMTestVariable_fileOne_h
#define DMTestVariable_fileOne_h // 声明全局变量
extern int globalVariable; void addOne();
void testStaticGlobal(); #endif
fileOne.c文件如下:
#include <stdio.h>
#include "fileOne.h" // 静态全局变量
static int staticGlobalVariable = ; void addOne()
{
// 全局变量加1
globalVariable += ;
} void testStaticGlobal()
{
// 静态全局变量加1
staticGlobalVariable += ;
printf("静态全局变量:%d\n",staticGlobalVariable);
}
main.c文件如下:
#include <stdio.h>
#include "fileOne.h" // 定义性声明全局变量
int globalVariable = ;
void test()
{
// 静态局部变量
static int staticLocalVariable = ;
staticLocalVariable += ;
printf("静态局部变量值:%d\n",staticLocalVariable);
} int main(int argc, const char * argv[])
{
int i;
// 局部变量测试
int localVariable = ;
printf("局部变量%d\n",localVariable); // 全局变量测试
addOne();
printf("全局变量:%d\n",globalVariable);
// 静态局部变量的测试
for (i = ; i < ; i++) {
test();
} // 静态全局变量
for (i = ; i < ; i++) {
testStaticGlobal();
}
return ;
}
结果如下:
总结如下:
全局变量,具有全局作用域,只需在一个源文件中定义,就可以作用于所有的源文件,当然其他不包含全局变量定义的源文件需要用extern关键字再次声明这个全局变量,如代码中的
// 定义性声明全局变量
int globalVariable = ;
全局变量,定义在main.c源文件中,在fileOne.c源文件中使用时有以下代码再次声明
// 声明全局变量
extern int globalVariable;
静态全局变量,只能在其所在文件模块中的函数中使用,其他文件模块中的函数不能访问。如代码中的
// 静态全局变量
static int staticGlobalVariable = ;
只能在fileOne.c源文件中使用,不能在main.c源文件中使用。
局部变量:只能在定义该变量的函数体内使用。如代码中的
// 局部变量测试
int localVariable = ;
只能在main函数中使用。
静态局部变量:在函数内定义,但当函数退出后,静态局部变量始终存在,其占用的内存单元不会被释放,直到程序结束时才被释放。退出函数后尽管该静态局部变量还存在,但是不能使用它,如果再次调用定义该静态局部变量的函数,它又可以继续使用,而且保存了上次调用之后留下的值。如代码中的
// 静态局部变量
static int staticLocalVariable = ;
第一次调用test()函数输出的此静态局部变量值为21,第二次调用函数test()输出的此静态局部变量值为22。
C语言_了解一下C语言中的四种存储类别的更多相关文章
- 对称加密和分组加密中的四种模式(ECB、CBC、CFB、OFB)
一. AES对称加密: AES加密 分组 二. 分组密码的填充 分组密码的填充 e.g.: PKCS#5填充方式 三. 流密码: 四. 分组密码加密中的四种模式: 3.1 ECB模式 优点: 1. ...
- JAVA基础学习之throws和throw的区别、Java中的四种权限、多线程的使用等(2)
1.throws和throw的区别 throws使用在函数外,是编译时的异常,throw使用在函数内,是运行时的异常 使用方法 public int method(int[] arr) throws ...
- Activity中的四种启动模式
在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. An ...
- C++中的四种转型操作符
在具体介绍C++中的四种转型操作符之前,我们先来说说旧式转型的缺点: ①它差点儿同意将不论什么类型转换为不论什么其它类型,这是十分拙劣的.假设每次转型都可以更精确地指明意图,则更好. ②旧式转型难以辨 ...
- JAVA中的四种引用以及ReferenceQueue和WeakHashMap的使用示例
简介: 本文主要介绍JAVA中的四种引用: StrongReference(强引用).SoftReferenc(软引用).WeakReferenc(弱引用).PhantomReference(虚引用) ...
- Java中的四种引用
引用定义 实际上,Java中存在四种引用,它们由强到弱依次是:强引用.软引用.弱引用.虚引用.下面我们简单介绍下这四种引用: 强引用(Strong Reference):通常我们通过new来创建一个新 ...
- mysql中四种存储引擎的区别和选择
前言 数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建.查询.更新和删除数据.不同的存储引擎提供不同的存储机制.索引技巧.锁定水平等功能,使用不同的存储引擎,还可以 ...
- JavaScript确定一个字符串是否包含在另一个字符串中的四种方法
一.indexOf() 1.定义 indexOf()方法返回String对象第一次出现指定字符串的索引,若未找到指定值,返回-1.(数组同一个概念) 2.语法 str.indexOf(searchVa ...
- JAVA中的四种JSON解析方式详解
JAVA中的四种JSON解析方式详解 我们在日常开发中少不了和JSON数据打交道,那么我们来看看JAVA中常用的JSON解析方式. 1.JSON官方 脱离框架使用 2.GSON 3.FastJSON ...
随机推荐
- java面向对象的三大特性——多态
多态 所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底 ...
- python3 第三章 - 程序的基本结构
1.编码 默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串. 当然你也可以为源码文件指定不同的编码: # -*- coding: cp-1252 -* ...
- Linux几个小杂碎点(更新中)
1 BIOS时间和系统时间问题 安装完CentOS后,系统时间是CST时间,而BIOS时间是UTC时间,因此系统时间会比BIOS时间快8个小时.如果您设置BIOS自动开机的话,就会总是差个8小时.需要 ...
- Struts2 (三)
1 Struts2的拦截器 Struts2拦截器在访问某个Action方法之前或之后实施拦截,拦截器是可插拔的,拦截器是AOP的一种实现. Struts2拦截器栈:将拦截器按一定顺序联结成一条链,在访 ...
- 安卓和IOS兼容问题
点击穿透 click延迟 scroll元素临界的bug android screen.w/h 不准 rem不准 scroll时动画失效 animate回调 最小字号限制 不同机型全屏自适应 andro ...
- java 多维数组遍历
java 多维数组遍历的顺序的性能问题 ps:下图为java多维数组内存分布原理.出自:http://math.hws.edu/javanotes/c7/two-dimensional-array.p ...
- typedef如何显示变量类型名
dsa typedef unsigned long int NUM; typedef unsigned short int Data; //为已经存在的类型起一个别名 //1.定义一个变量 unsig ...
- 一道python面试题引发的血案
这里说的是一道阿里校招的面试题:一行代码实现对列表a中的偶数位置的元素进行加3后求和? 今天去面试同样遇到了这个题目,这道题考察的是对python高阶函数map/filter的灵活运用(具体的使用方法 ...
- My Calendar III
class MyCalendarThree(object): """ Implement a MyCalendarThree class to store your ev ...
- javascript中的Date对象和Math对象
1.Date对象 1.创建Date对象 var time1=new Date() 方法1:不指定参数 var time1=new Date(); alert(time1.toLocaleString( ...