C语言学习笔记:12_变量的存储方式和生存期
/*
* 12_变量的存储方式和生存期.c
*
* Created on: 2015年7月5日
* Author: zhong
*/
#include <stdio.h>
#include <stdlib.h> /**
* 从变量的作用域分: 全局变量,局部变量
* 从变量存在的时间(生命周期)分:静态存储方式。动态存储方式
*
* 静态存储方式:在程序执行期间由系统分配固定的存储空间的方式
* 动态存储方式:在程序执行期间依据须要进行动态的分配存储空间的方式。
*
* 数据存放的位置:静态存储区,动态存储区
*
* 1:全局变量所有存放在静态存储区,当程序開始执行时给全局变量分配存储区。结束后释放。在执行期间占领固定存储单元,而不是动态地进行分配和释放。
* 2:动态存储区:形式參数,函数中定义的变量(不带statickeyword),函数调用时的现场保护和返回地址
* 动态存储区内分配存储单元,在程序整个执行期间都不会释放。
*
* 在c语言中,每个变量和函数都有两个属性:数据类型(如:int,float)和数据的存储类别(静态,动态存储)。
*
* c语言中存储类别包含4种:自己主动的(auto,默认) ,静态的(static),寄存器的(register),外部的的(extern)
* 存储类别不同,变量的作用域和生存期也不同。
*
*-------------------------------------------
* 一:局部变量的存储类别:
* 1:自己主动变量(默认的):在函数中的局部变量。假设不专门声名为static的。都是动态地分配存储空间的,数据存储在动态存储区中。 * 调用函数会给这些变量分配存储空间。结束时自己主动释放存储空间
* 如:函数的形參。局部变量。
* 自己主动变量用keywordauto作存储类别的声明。
*
* int f(int a){//形參
* auto int b,c=3; //int b,c=3; 自己主动局部变量。auto当然能够省略(我们平时就是省略的)
* }
*
* 2:静态局部变量(static局部变量):仅仅是在局部变量int a;前面加个statickeyword static int a; 数据存储在静态存储区中。
* 特点:当函数结束后。静态局部变量的存储单元不会释放。当下次再调用这个函数时,这个值就是上一次调用时结束时产生的值。
*
* 静态局部与自己主动局部变量比較:
* 1:静态局部变量是在编译时赋初值,仅仅赋初值一次,在程序执行时它已经有初值。以后每次调用函数时不再又一次赋初值而仅仅是保留上次函数调用结束时的值
* 2:动态局部变量赋初值,不是在编译时进行的,而是在函数调用时进行的,每调用一次,函数又一次比例一次初值。
* 3:定义静态局部变量时不赋初值,系统会自己主动赋初值0,或空字符‘\0’。对于自己主动变量来说,假设定义时不赋初值,系统会随机分配一个不确定的存储单元。所以值不确定。
* 4:静态局部变量在函数调用结束后仍然存在,可是其他函数不能引用。 *
* 静态局部变量使用场景:须要保留函数上一次调用结束时的值
* 如:输出1到5的阶乘值
* int fac(int n){
* static int fac=1;
* fac=fac*n;
* return fac;
* }
*
* int main(){
* int i;
* for(i=1;i<=5;i++)
* printf("%d!=%d\n",i,fac(i));
* }
*
* 3:寄存器变量(register): 将变量保存到cpu的寄存器中。
* 说明:
* 一般变量(静态,动态存储方式)的值都 存放在内存中的,当程序用到上"控制器"发生指令将内存中这个变量的值送到"运算器"中进行运算,
* 运算后。再从运算器将数据送到内存中存放。
*
* 为什么要操作寄存器变量:
* 比如在函数中执行1000次循环,每次循环中都 要引用局部变量(对某个变量频繁存取),假设每次都由“控制器”发送指令从内存中“存取”变量值,会花费不少时间。
* 将局部变量的值放在cpu的寄存器中,须要用的时间胻从寄存器取出參加运算,不必从内存中去存取。 速度超快的说。 *
* 声明寄存器变量:register int f;
*
* 因为计算机的发展,优化的编译系统能够自己主动识别使用频繁的变量,从而自己主动将这些变量放在寄存器中。所以实际编程中,程序猿不须要过多指定这样的 变量。
*
*-------------------------------
*二:全局变量的存储类别:
*
* 全局变量都是存放在静态存储区中的,因此它们的生存期是固定的。 存在于程序执行的整个过程。
* 尽管生命周期是固定的,可是全局变量的作用域是不确定的,不同的存储类别作用域不同。
*
* 普通情况下假设全局变量(外部变量)不在文件的开头定义(整个源文件)。其作用域在定义处開始,到本程序文件的未尾。 定义处之前的函数不能使用。 *
* 假设不在文件开关定义,又想定义处之前的函数能使用这个全局变量,就要对全局变量进行作用域扩展
* 1:在一个文件内扩展外部变量的作用域 (extern)
* 在函数引用这个在函数之后定义的外部变量时,使keywordextern对这个变量作“外部变量声明”:表示将外部变量的作用域扩展到此位置
* 如:
* int fun(){
* extern int A; //extern对这个变量作“外部变量声明”
* //...在这个函数后面语句就能够使用这个外部变量了
* }
* int A=20; //在函数之后声名的外部变量
*
* 2:将外部变量的作用域扩展到其他文件
* 将其他源文件里的全局变量扩展到本源文件加也是加个externkeyword就可以。
*
* 如:
* file 1.c:
* int A=20;
* int max(){
* A=3;
* }
*
* file2.c:
* int funk(){
* extern int A; //将file 1.c 中定义的全局变量a扩展到这个文件,当作这文件的局部变量,int可省略
* A=34;
* }
* extern A;//将file 1.c 中定义的全局变量a扩展到这个文件,当作这文件的外部变量。在此之后的函数可用。之前的函数不可用
* int funk(){
* A=3; //在此之后的函数可用
* }
*
* (静态外部变量)
* 3:将外部变量的作用域限制在本文件里(不让其他文件訪问):仅仅须要在定义外部变量时加入statickeyword就可以。
* 同一时候。加了statickeyword的全局变量的名称,其他文件也能够使用这个文件,不会发生冲突
*
* static int A=20; //这样其他文件就不能訪问这个外部变量了。
* int main(){
*
* }
*
*
*小结:
* 一: static声明一个变量的作用:
* 1:对局部变量用static声明。把它分配在静态存储区。这变量在整个程序执行期间不释放
* 2:对全局变量用static声明,则这变量的作用域仅仅限于 本文件模块。其他文件不可引用
*
*二: 声明存储类型的作用
* 对于局部变量来说,声明存储类型的作用是指定变量存储的区域(静态存储。动态存储,寄存器),以及由此产生的生存期的问题
* 对于全局变量,因为在编译时分配内存的。都 存放在静态存储区中,声明存储类型的作用是变量作用域的扩展问题,无它。 *
*
*/
//局部静态。动态变量
void local_static_auto(int a) {
auto int b = 1; //auto能够省略 自己主动变量
static int c = 3; //定义静态变量,程序执行期间。其存储单元不会释放。这语句仅仅会在编译时执行一次,执行后不再执行。
//当第二次调用时。不会再又一次赋初值3,仅仅会使用前一次调用后保存的值
printf("第%d次执行:b=%d,c=%d,a+b+c=%d\n", a, b, c, (a + b + c)); c++; //c自增后保存在存储单元中。不释放,以便函数下次被调用时使用 .
b++; //自己主动变量在这里自增后也没用。因为
}
void test_local_static_auto() {
int i;
for (i = 1; i < 5; i++) {
local_static_auto(i);
}
/**
* output:
第1次执行:b=1,c=3,a+b+c=5
第2次执行:b=1,c=4,a+b+c=7
第3次执行:b=1,c=5,a+b+c=9
第4次执行:b=1,c=6,a+b+c=11
*/
} //求n的阶乘
int fac(int n) {
static int fac = 1; //记录乘积结果
fac *= n;
return fac;
}
void test_fac() {
int i;
for (i = 1; i <= 5; i++)
printf("%d!=%d\n", i, fac(i));
/*1!=1
2!=2
3!=6
4!=24
5!=120*/
} extern a;//将11_全局变量.c中定义的全局变量a扩展到这个文件,在此之后的函数可用。之前的函数不可用 //使用此函数之后 定义的外部变量
void use_extern_variable(){
extern int A; //把外部变量a的作用域扩展到从此处開始
// extern A; //类型名可写可不写
A=30;
printf("extern_variable A=%d ,other file a=%d\n",A,a);
}
int A=20;
int main12() { // test_local_static_auto();
// test_fac();
use_extern_variable();
extern a; //将11_全局变量.c中定义的全局变量a扩展到这种方法里面,其他方法不能用
printf("%d",a); return 0;
}
C语言学习笔记:12_变量的存储方式和生存期的更多相关文章
- (C/C++学习笔记) 九. 变量的存储类型
九. 变量的存储类型 ● 变量的存储类型(见附页) ● 注释 ①对于自动变量,它属于动态存储方式. 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式.由此看来,一个 ...
- java笔记之变量的存储方式
1.java变量存储域 java变量的存储区域主要放在以下几个地方: (1)寄存器:可以说是最快的存储区,在C/C++中可以声明寄存器变量,但是在java中不能声明寄存器变量,只是编译器在编译时确定. ...
- [C语言学习笔记四]变量与系统的交互
使用 const 创建常量和使用 volatie 优化变量 C语言中使用 const 定义常量. 例如: const INT a = 10; 此处如果添加a = 20;,编辑器则会报错,因为此处 a ...
- Go语言学习笔记(二) [变量、类型、关键字]
日期:2014年7月19日 1.Go 在语法上有着类 C 的感觉.如果你希望将两个(或更多)语句放在一行书写,它们 必须用分号分隔.一般情况下,你不需要分号. 2.Go 同其他语言不同的地方在于变 ...
- c语言学习笔记 const变量
在c语言的编程过程中经常会遇到有常数参加运算的运算,比如这种. int a=100*b; 这个100我们叫常数或者叫常量,但是程序中我们不推荐这种直接写常数的方法,有两个缺点. 第一是程序可读性差. ...
- Go语言学习笔记1 变量,类型以及赋值
1.变量 1.1 声明变量 使用var关键字可以创建一个指定类型的变量: var i int = 0 var i = 0 var i int 以上三个表达式均是合法的,第三个表达式会将i初始化为int ...
- Go语言学习笔记(2)——变量、常量
1. 变量(变量由字母.数字和下划线组成,且不能以数字开头!) 1.1 第一种 var name type // 未赋值时使用默认值 name = value 1.2 第二种: 根据所赋的值 ...
- c语言学习笔记之结构体存储
今天讲讲结构体存储问题 首先,结构体简单说是对不同类型的封装,一开始我们可能会想结构体在内存中的存储的大小是直接元素的和 例如 我们可能会觉得是 结构体大小=int(4个字节)+ short(2个字节 ...
- C语言的变量存储方式和生存期
2020.2.28日,封城一个多月了,紧邻毕业期,我在家抽空学习一下C. 看到了变量的存储方式和生存期这一章节,下面就是我整理的内容 下面是用于理解静态局部变量这个概念所写的代码,主要是需要分析一下函 ...
随机推荐
- manjaro安装virtualbox教程
安装前需要知道 你需要知道你当前的内核版本 uname -r,比如输出了4.14.20-2-MANJARO那么你的内核版本为414 安装VirtualBox sudo pacman -S virtua ...
- .less为后缀的文件是什么
.less为后缀的文件是什么 一.总结 1.less是什么:LESS 为 Web 开发者带来了福音,它在 CSS 的语法基础之上,引入了变量,Mixin(混入),运算以及函数等功能,大大简化了 CSS ...
- 循环体(for/while)循环变量的设置
1. 求滑动(移动)平均(moving average) double partialSum = 0; for (int i = 0; i < M-1; ++i) partialSum += A ...
- 91.生成ini文件并写入和读取ini文件
写入 WritePrivateProfileStringA("hello money", infx[i].name, money, "1.ini"); 按照字符 ...
- python之经典猜数字
题目:猜数字1.让用户输入1-20,猜数字,可以猜5次.2.每次有提示,大了,或者小了!3.如果超过5次,提示game over. # !/usr/bin/env python # -*- codin ...
- 洛谷 P1178 到天宫做客
P1178 到天宫做客 题目描述 有一天,我做了个梦,梦见我很荣幸的接到了猪八戒的邀请,到天宫陪他吃酒.我犹豫了.天上一日,人间一年啊!当然,我是个闲人,一年之中也没有多少时日是必须在人间的,因此,我 ...
- nginx源代码分析--事件模块 & 琐碎
通过HUP信息使得NGINX实现又一次读取配置文件,使用USR2信号使得NGINX实现平滑升级. 在nginx中有模块这么一说,对外全部的模块都是ngx_module_t类型,这个结构体作为全部模块的 ...
- 小贝_redis web管理界面工具安装
RedisWEB管理界面工具安装 一.概述 二.文件下载 三.安装过程 一.概述 1.因为redis是基于C/S的方式开发.也就是说,仅仅要满足于redis的client通信要求的,都能够作为redi ...
- C#委托与事件(生动故事)
[委托] 1,工人Peter按工作步骤向老板报告的程序. 程序: using System; using System.Collections.Generic; using System.Linq; ...
- RMAN异机复制数据库(相同路径)
有完整的备份,新的数据库datafile.controfile.logfile所在目录结构和原数据库一样. 创建好adump.bdump.cdump.udump等目录. 1.恢复参数文件. 设置环境变 ...