/*
* 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_变量的存储方式和生存期的更多相关文章

  1. (C/C++学习笔记) 九. 变量的存储类型

    九. 变量的存储类型 ● 变量的存储类型(见附页) ● 注释 ①对于自动变量,它属于动态存储方式. 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式.由此看来,一个 ...

  2. java笔记之变量的存储方式

    1.java变量存储域 java变量的存储区域主要放在以下几个地方: (1)寄存器:可以说是最快的存储区,在C/C++中可以声明寄存器变量,但是在java中不能声明寄存器变量,只是编译器在编译时确定. ...

  3. [C语言学习笔记四]变量与系统的交互

    使用 const 创建常量和使用 volatie 优化变量 C语言中使用 const 定义常量. 例如: const INT a = 10; 此处如果添加a = 20;,编辑器则会报错,因为此处 a ...

  4. Go语言学习笔记(二) [变量、类型、关键字]

    日期:2014年7月19日 1.Go 在语法上有着类 C 的感觉.如果你希望将两个(或更多)语句放在一行书写,它们 必须用分号分隔.一般情况下,你不需要分号.   2.Go 同其他语言不同的地方在于变 ...

  5. c语言学习笔记 const变量

    在c语言的编程过程中经常会遇到有常数参加运算的运算,比如这种. int a=100*b; 这个100我们叫常数或者叫常量,但是程序中我们不推荐这种直接写常数的方法,有两个缺点. 第一是程序可读性差. ...

  6. Go语言学习笔记1 变量,类型以及赋值

    1.变量 1.1 声明变量 使用var关键字可以创建一个指定类型的变量: var i int = 0 var i = 0 var i int 以上三个表达式均是合法的,第三个表达式会将i初始化为int ...

  7. Go语言学习笔记(2)——变量、常量

    1. 变量(变量由字母.数字和下划线组成,且不能以数字开头!)      1.1 第一种 var name type // 未赋值时使用默认值 name = value 1.2 第二种: 根据所赋的值 ...

  8. c语言学习笔记之结构体存储

    今天讲讲结构体存储问题 首先,结构体简单说是对不同类型的封装,一开始我们可能会想结构体在内存中的存储的大小是直接元素的和 例如 我们可能会觉得是 结构体大小=int(4个字节)+ short(2个字节 ...

  9. C语言的变量存储方式和生存期

    2020.2.28日,封城一个多月了,紧邻毕业期,我在家抽空学习一下C. 看到了变量的存储方式和生存期这一章节,下面就是我整理的内容 下面是用于理解静态局部变量这个概念所写的代码,主要是需要分析一下函 ...

随机推荐

  1. POJ Fence Repair(优先队列)

    Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 51346   Accepted: 16857 De ...

  2. 前端项目中常用es6知识总结 -- Async、Await让异步美如画

    项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2. ...

  3. BZOJ3192: [JLOI2013]删除物品(splay)

    Description   箱子再分配问题需要解决如下问题:  (1)一共有N个物品,堆成M堆.  (2)所有物品都是一样的,但是它们有不同的优先级.  (3)你只能够移动某堆中位于顶端的物品.  ( ...

  4. C#之在treeview中鼠标点击的所选的节点触发事件

    一.背景 如下图所示,我想实现通过鼠标点击treeview的根节点,然后在文本框控件中显示鼠标点击的节点号. 二.程序实现 因为是要通过鼠标点击才发生的事情,所以这属于一个事件,需要触发才行,刚开始不 ...

  5. Hibernate之API初识及增删改查实现

    声明:关于hibernate的学习.非常大一部分东西都是概念性的. 大家最好手里都有一份学习资料,在我的博文中.我不会把书本上的概念一类的东西搬过来.那没有不论什么意义.关于hibernate的学习, ...

  6. vue 图片lazyload

    今天看到我一醉哥的一篇朋友圈分享:<不如我们从头来过 | 掘金> 看完之后,百感交集,互联网的浪潮使创业公司如雨后春笋般崛起, 每一个初创公司都会有一群怀着美好愿景的小伙伴, 但是当寒冬来 ...

  7. HttpWatch--time chart分析

    这是一个IE的插件,下载可以点这里.下载后解压如下图所示,一共有4个文件.HttpWatch Professional是单独软件,可以单独使用. 解压后有四个文件 插件安装时,只需运行httpwatc ...

  8. c++11 多线程 -- 基本使用

    c++11 多线程 – 基本使用 前言:这篇文章仅针对没有使用过c++11线程库的童鞋来高速入门,也是自己的一个简单记录,内容比較基础. 1.线程的基本使用 2.相互排斥量 3.条件变量 4.原子变量 ...

  9. Spring 使用Cache(转)

    从3.1开始Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事物管理的支持.Spring Cache是作用在方法上的,其核心思想是:当我们在调用一个缓存方法时会把该方法参数 ...

  10. DMA 如何查看它有没有传输完成 传输完成再开启

    摘自:https://blog.csdn.net/zzwdkxx/article/details/9026173 /////////////////////////////////////////// ...