动态储存方式和静态储存方式

变量从存在的时间(生存期)角度来分,可以分为动态储存方式和静态储存方式。

所谓静态存储方式是指在程序运行开始时由系统分配固定的储存空间的方式。

动态储存方式则是在程序运行期间根据需要进行动态的分配储存空间的方式。

存储空间分为3部分:(1)程序区(2)静态存储区(3)动态存储区。

在C语言中,每一个变量和函数都有两个属性:数据类型和数据的存储类别。

对数据型(如整型,字符型等):储存类别指的是数据在内存中的储存方式。具体包含四种:自动的(auto),静态的(static),寄存器的(register),外部的(extern)。根据变量的储存类别,可以知道变量的作用域和生存期。

1、auto变量

函数中的局部变量,如不专门声明为static储存类别,都是动态的分配存储空间(栈),数据存储在动态存储区中。

函数中的形参和在函数中定义的变量(包括在复合语句中定义的变量),都属此类,在调用该函数时,系统会给它们分配存储空间,在函数调用结束时,自动释放这些存储空间。

例:int f(int a)   /*定义为f函数,a为形参*/

  {

    auto int b,c=3;  /*定义b,c为自动变量*/

  }

关键字auto可以省略,auto不写则默认为“自动存储类别”。

2、用stastic声明局部变量

有时希望函数中的局部变量的值在函数调用结束后不消失,即存储单元不释放。

这时就应指定局部变量为“静态局部变量”,用static进行声明。

例:

#include <stdafx.h>
#include<stdio.h>

int f(int a)
{
    auto b=0;
    static int c=3;
    b=b+1;
    c=c+1;
    return(a+b+c);
}
void main()
{
    int a=2,i;
    for(i=0;i<3;i++)
    {
        printf("%d\n",f(a));
    }
}

说明:(1)静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在函数整个运行期间都不释放,而自动变量属于动态存储类别,占动态存储空间而不占静态存储空间,函数调用结束后释放。

(2)对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时已有初值。

(3)若在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符型变量),对自动变量来说,不赋初值则它的值是一个不确定的值。

(4)虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的。

例:输出从1到5的阶乘值。

#include <stdafx.h>
#include<stdio.h>

int fac(int a)
{
    static int f=1;
    f=f*a;
    return(f);
}
void main()
{
    int i ;
    for(i=1;i<=5;i++)
    {
        printf("%d!=%d\n",i,fac(i));
    }
}

3、register变量

一般情况下,变量存放在内存中。

但若一些变量使用过于频繁则会浪费很多时间(cpu处理数据与内存读取数据有时间差)。

为提高程序执行效率,C语言允许将局部变量的值放在CPU寄存器中,需要时直接取出参加运算,不必再到内存中去存取。

这种变量称为寄存器变量,用关键字register作声明。

例:输出1到n阶乘的值。

#include <stdafx.h>
#include<stdio.h>

int fac(int n)
{
    static int i ,f=1;
    for(i=1;i<=n;i++)
    {
        f*=i;
    }
    return(f);
}
void main()
{
    int i,n;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        printf("%d!=%d\n",i,fac(i));
    }
}

4、用extern声明外部变量

有时要用extern来声明外部变量,以扩展外部变量的作用域。

例:

#include <stdafx.h>
#include<stdio.h>

int max(int x,int y)
{
    int z;
    z=x>y?x:y;
    return(z);
}
void main()
{
    extern int A,B;
    printf("%d\n",max(A,B));
}
int A=13,B=8;

其实extern的作用就是告诉编译器读到AB时知道其为全局变量,其值可能在程序的任意一个地方。

原文地址:https://www.cnblogs.com/lvfengkun/p/10349385.html

时间: 2024-11-08 02:55:39

动态储存方式和静态储存方式的相关文章

堆/栈/动态存储方式/静态存储方式

动态存储方式 所谓动态存储方式是指在程序运行期间根据需要进行动态的分配存储空间的方式.动态存储变量是在程序执行过程中,使用它时才分配存储单元, 使用完毕立即释放. 典型的例子是函数的形式参数,在函数定义时并不给形参分配存储单元,只是在函数被调用时,才予以分配, 调用函数完毕立即释放.如果一个函数被多次调用,则反复地分配. 释放形参变量的存储单元. 静态存储方式 所谓静态存储方式是指在程序编译期间分配固定的存储空间的方式.该存储方式通常是在变量定义时就分定存储单元并一直保持不变, 直至整个程序结束

Android中BroadcastReceiver的两种注册方式(静态和动态)详解

今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来接收来自系统和应用中的广播.在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能:当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作:当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户

ubuntu修改ip获取方式(静态,动态)

1.直接修改系统配置文件 ubuntu的网络配置文件是:/etc/network/interfaces a.动态ip方式 auto eth0 iface eth0 inet dhcp 用下面的命令使网络设置生效: sudo /etc/init.d/networking restart b.静态ip方式 auto eth0 iface eth0 inet static address 192.168.1.22 gateway 192.168.1.1 netmask 255.255.255.0 #n

Spring 使用静态工厂方式实例化Bean

知识点介绍: 静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取. [转载使用,请注明出处:http://blog.csdn.net/mahoking] 操作步骤: 1.创建Speaker对象. /** * 静态工厂类 * */ public class Speaker { private String name ; private String t

十四、Android学习笔记_Android回调函数触发的几种方式 广播 静态对象

一.通过广播方式: 1.比如登录.假如下面这个方法是外界调用的,那么怎样在LoginActivity里面执行登录操作,成功之后在回调listener接口呢?如果是平常的类,可以通过构造函数将监听类对象传入即可.但是在Activity中不能传递监听对象,所以考虑使用广播来实现. public void login(final LoginOnClickListener listener) { Intent intent = new Intent(context, LoginActivity.clas

通过FreeMarkerclasspath加载方式生成静态页面

package htmlskin; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Calend

Linux:Vmware安装linux虚拟机,桥接方式配置静态IP后重启网卡,提示:Error,some other host already uses address 10.252.252.21...

问题: Vmware安装linux虚拟机,桥接方式配置静态IP后重启网卡,提示:Error,some other host already uses address 10.252.252.21... 思路: 网上查找资料,得到解决方案如下: 编辑 /etc/sysconfig/network-scripts/ifup-eth, 将 (注:RHEL5.3 )if ! arping -q -c 2 -w 3 -D -I ${REALDEVICE} ${IPADDR} ; thenecho $”Err

java动态获取WebService的两种方式(复杂参数类型)

java动态获取WebService的两种方式(复杂参数类型) 第一种: @Override public OrderSearchListRes searchOrderList(Order_FlightOrderSearchRequest request) { Object myAllMessage; OrderSearchListRes response = null; try { String endpoint = carGlobalSetting.getEndpoint(); JaxWsD

动态加载vs静态加载

动态加载: 1:灵活,可以在需要的时候用LoadLibrary进行加载,在不需要的时候用FreeLibrary进行卸载,这样可以不必占用内存. 2:可以在没有dll时候发现,而不致程序报错. 3:加载程序中有条件才运行的库. 4:热更新,在不停止程序的前提下进行更新. 5:复杂一些,需要显示获得函数地址. 6:dll没有对应的lib文件,此时只能进行动态加载. 静态加载: 1:简单方便 2:没有dll时,系统报错 3:加载运行很久的库 4:dll必需有相应的lib文件 加载方法: 1.确保有a.