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 ...
随机推荐
- Android 基础:常用布局 介绍 & 使用(附 属性查询)
Android 基础:常用布局 介绍 & 使用(附 属性查询) 前言 在 Android开发中,绘制UI时常需各种布局 今天,我将全面介绍Android开发中最常用的五大布局 含 Andr ...
- 通过Azure 存储账号URL鉴别是标准磁盘还是高性能磁盘
对于不知道虚拟机磁盘是标准磁盘还是高性能磁盘时,我们可以通过nslookup解析存储账号的URL,来判断存储账号的类型,从而得知虚拟磁盘的类型 1.标准存储账号的解析结果,字母"st&quo ...
- Can’t open /dev/* exclusively. Mounted filesystem?解决
1 错误提示:Can’t open /dev/* exclusively. Mounted filesystem? 做完软件RAID之后,根据鸟哥书上的操作,其实没有真正删除软件RAID,导致出现如下 ...
- ueditor表格边框没有颜色的解决
问题: 用ueditor画表格,会发现表格存在,但是表格边框没有颜色. 解决方法: 需要对js文件中的样式进行修改,这里我引用的编辑器样式文件是ueditor.all.min.js,所以先找到该文件, ...
- 用 chrome 调试 node.js 代码
1.全局安装 node-inspector cnpm install -g node-inspector 2.启动node项目入口文件,如 node --inspect index.js 3.控制台 ...
- 【转】 C++易混知识点4: 自己编写一个智能指针(Reference Counting)学习auto_ptr和reference counting
这篇文章建大的介绍了如何编写一个智能指针. 介绍: 什么是智能指针?答案想必大家都知道,智能指针的目的就是更好的管理好内存和动态分配的资源,智能指针是一个智能的指针,顾名思义,他可以帮助我们管理内存. ...
- 【转】sed 学习笔记
一 . sed 简介 1 . 功能 sed 是一种流编辑器,所谓流编辑器是指能够对来自文件或者管道的输入流进行基本的文本转换的工具,比方说查找替换删除等. 2 . 最简单的运作机制 sed ...
- Git的基本原理与常用命令[二]
标签(linux): git 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 git 的四个区域 四种状态 常用命令 git add #加入暂存(索引区) git ...
- 使用localhost可以访问,但使用本地ip+端口号无法访问
今天想使用ip访问本机的iview-admin项目,结果怎么配置都无法访问,根据iview工程执行的命令npm run dev了解到是webpack配置的问题,打开工程里的node_modules文件 ...
- jquery实现上传图片本地预览效果
html: <img id="pic" src="" ><input id="upload" name="fil ...