当前课程知识点:C语言程序设计 > 第8章 函数 > 8.5 变量的存储类型 > 变量的存储类型
同学们大家好
我们今天来讲变量的存储类型
变量的存储类型
指的是变量占用内存空间的方式
也称为存储方式
分为静态存储和动态存储两种
静态存储类型的变量是指在程序运行期间
由系统分配固定的内存单元
并一直保持不变
直至整个程序结束
内存空间才被释放
前面所介绍的全局变量即属于此类存储方式
动态存储类型的变量是在程序运行期间
根据需要进行动态分配内存单元
使用完毕立即释放
典型的例子是函数的形式参数
即属于此类存储方式
静态存储类型的变量存储在操作系统静态存储区
而动态存储类型的变量
存储在操作系统动态存储区
在C语言中
对变量的存储类型说明有以下四种
auto---------自动型
register-----寄存器型
static -------静态型
extern-------外部型
例如auto char c1
c2定义c1c2为自动字符变量
register i定义i为寄存器型变量
static int ab定义a
b为静态整型变量 extern int x
y定义xy为外部整型变量
而变量定义的完整形式应为
存储类型说明符 数据类型说明符
变量名1变量名2…变量名n
下面看第一种
auto型变量
又叫自动型变量
其定义格式为
[auto] 意思是auto关键字可以省略
数据类型说明符 变量名1
变量名2…变量名n
其中
存储类型说明符auto关键字可以省略
而且自动变量只能再函数内
或复合语句中定义
它属于局部变量
动态存储类型
例如
func函数中定义的整型变量i j k
就属于自动变量
它省略了auto关键字
等价于 auto int ijk
注意
auto关键字不能修饰全局变量
例如
这个程序中
在全局变量的定义
int k前面加上auto关键字
将会导致编译错误
注意
在函数外部定义的没有带存储类型说明符
的全局变量是外部变量
属于静态存储类型
如这里的全局变量k
下面看外部变量
外部变量和全局变量是对同一类变量的
两种不同角度的提法
全局变是是从它的作用域提出的
外部变量从它的存储方式提出的
表示了它的生存期
它属于静态存储类型
例如
我们的工程中有两个源文件
在源文件prg1.cpp中定义了全局变量a和b
同时声明了外部函数max
然后在main函数中
对全局变量a和b赋值为4 5
然后调用max函数
将计算结果赋值给c
而在另一个源文件prg2.cpp中
通过extern int a
b语句声明了全局变量a和b
然后在max函数的实现代码中
返回了a b的最大值
从而在main函数最后得到c的值为
a b的最大值5
这两个源文件
在经过编译
运行后便得到运行结果
max=5 下面看静态变量
使用static关键字修饰的变量
叫做静态变量
静态变量属于静态存储类型
包括静态局部变量和静态全局变量
首先来看静态局部变量
在局部变量的说明前加上static
就构成静态局部变量
例如
static int a b 定义了静态整型变量a b
static float array[5] = {12345}
定义并初始化了静态浮点数组
静态局部变量
仍然属于局部变量
其作用范围仍然是
仅能在其所在函数中使用
不能在其他函数中使用
例如这个例子中
main函数试图引用
func函数中定义的静态局部变量s
就会产生错误
下面通过静态局部变量和自动型变量相互比较来
了解静态局部变量的特性
静态局部变量有如下一些特性
第一由于其采用静态存储方式
故它的值能在函数调用结束后保持下来
而不像自动型局部变量
它的内存在函数调用结束后将被释放
从而无法保留其上一次函数调用结束时的值
第二静态局部变量若在定义时未赋初值
则系统自动赋初值0
而自动型变量若定义时未赋初值
则其值将是一个随机数
第三静态局部变量赋初值只执行一次
即第一次使用该变量时对其赋初值
而自动变量赋初值每次都要执行
例如
左右两个程序
均定义了func函数
在函数中定义了变量j
并赋初值为0
然后执行++j让j的值加1
最后输出j的值
main函数都是循环5次调用func函数
但输出结果却是不同的
我们看到左边的程序输出了5个1
也就是说每次调用func函数输出的j的值都是1
而右边的输出了1 2 3 4 5
为什么会不同呢
原因就是左边func函数中的变量j是自动型变量
其每次运行都要对j重新分配内存并初始化为0
然后执行加1操作
从而每次都会输出1的结果
而右边的func函数中定义的变量j是静态的
该变量在程序运行过程中
系统只会为其分配1次内存
并初始化为0
这种初始化操作也只进行1次
即第一次调用func函数时执行
而后每次调用func函数时
不再为其执行初始化为0的操作
而++j操作
将会在上一次调用结束后
j的值的基础上加1
从而看到了j的输出
分别是1 2 3 4 5这样的结果
这就是静态局部变量能够在函数调用束时
保持其值的特性
下面来看静态全局变量
静态全局变量
就是在全局变量前面加static关键字构成的变量
全局变量冠以static关键字修饰后
将会使得该全局变量只能在
当前源文件中使用
这就是静态全局变量的特性
即 静态全局变量只在
定义该变量的源文件内有效
例如
这个例子
在prg1.cpp源文件中
定义了静态全局变量ch
而在另一个源文件prg2.cpp中试图
试图通过extern char ch语句
来引用prg1.cpp
中定义的全局变量ch时
就会产生错误
下面来看寄存器变量
这种变量存放在CPU的寄存器中
使用时
不需要访问内存
而直接从寄存器中读写
这样可提高效率
寄存器变量的说明符是register
属于动态存储类型
例如
这个程序中定义了寄存器变量i和s
通过循环来计算1加到100的和
由于使用了寄存器 将使得程序的执行效率有所提高
寄存器变量的默认类型是int型
这里register i等价于register int i
需要说明的是
只有局部自动变量和形式参数
才可以定义为寄存器变量
全局变量不可定义为寄存器类型
好同学们
今天的内容就讲到这里
我们下次再见
-计算思维与计算机
--计算思维与计算机
--计算思维与计算机
--计算思维和计算机
-2.1 程序设计语言的发展及其特点和应用
--程序设计语言的特点及发展
- 2.2 C语言程序的基本结构及编制C语言程序的基本步骤
--C语言程序的结构和编制步骤
-3.1 C语言的数据类型
--C语言的数据类型
--C语言的数据类型
-3.2 常量
--常量
--常量
-3.3 什么是变量
--什么是变量
--什么是变量
-3.4 如何进行算术运算
--如何进行算术运算
--如何进行算术运算
-3.5 赋值运算符和逗号运算符
--赋值运算符和逗号运算符
-3.6 数据类型转换
--数据类型转换
--数据类型转换
-4.1 格式化输出printf
--格式化输出
-4.2 格式化输入scanf及字符数据的非格式化输入输出
--格式化输入
-5.1 关系运算符和关系表达式
--关系运算符和关系表达式
-5.2 逻辑运算符和逻辑表达式
--逻辑运算符和逻辑表达式
-5.3 条件运算符和条件表达式
--条件运算符和条件表达式
-5.4 if语句
--if语句
--if语句
-5.5 switch语句
--switch语句
--switch语句
-6.1 while语句
--while语句
--while语句
--do-while语句
-6.2 for语句
--for语句
--for语句
-6.3 循环的嵌套
--循环的嵌套
--循环的嵌套
-6.4 break语句和continue语句
--break和continue语句
-7.1 一维数组的定义和引用
--一维数组的定义和引用
-7.2 一维数组的赋值
--一维数组的赋值
--一维数组的赋值
-7.3 二维数组的定义和引用
--二维数组的定义和引用
-7.4 二维数组的赋值
--二维数组的赋值
--二维数组的赋值
-7.5 字符串的本质
--字符串的本质
--字符串的本质
-7.6 字符串操作的常用函数
--字符串常用函数
-7.7 字符串数组
--字符串数组
--字符串数组
-8.1 函数概述
--函数概述
--函数概述
-8.2 有参函数
--有参函数
--有参函数
-8.3 函数参数的传递方式
--函数参数的传递方式
-8.4 变量的作用域和生存期
--变量的作用域和生存期
-8.5 变量的存储类型
--变量的存储类型
--变量的存储类型
-8.6 函数的嵌套和递归调用
--函数的嵌套和递归调用
-8.7 函数的作用域与封装
--函数的作用域与封装
-9.1 指针变量的概念(上)
--指针变量的概念(上)
-9.2 指针变量的概念(下)
--指针变量的概念(下)
-9.3 指向一维数组的指针变量
--指向一维数组的指针变量
-9.4 指向二维数组的指针变量(上)
--指向二维数组的指针变量(上)
-9.5 指向二维数组的指针变量(下)
--指向二维数组的指针变量(下)
-9.6 动态内存分配
--动态内存分配
--动态内存分配
-10.1 编译预处理
--编译预处理
-11.1 用户自己建立数据类型
--用户自己建立数据类型
-11.2 定义结构体类型变量
--定义结构体类型变量
-11.3 结构体变量的引用与初始化
-11.4 结构体数组
--结构体数组
--结构体数组
-11.5 指向结构体类型数据的指针
--指向结构体类型数据的指针
-12.1 文件的基本概念和文件指针
--文件的基本概念和文件指针
-12,2 文件的打开和关闭
--文件的打开和关闭
--文件的打开和关闭
-12.3 文本文件读写
--文本文件读写
--文本文件读写
-12.4 二进制文件读写
--二进制文件读写
--二进制文件读写