精华内容
下载资源
问答
  • 存储种类有四种:自动(auto),外部(extern),静态(static)和寄存器(register),缺省类型为自动(auto)。而这里的数据类型则是和我们在第四课中学习到的名种数据类型的定义是一样的。说明了一个变量的数据类型后,还可...

    [存储种类] 数据类型 [存储器类型] 变量名表

    在定义格式中除了数据类型和变量名表是必要的,其它都是可选项。存储种类有四种:自动(auto),外部(extern),静态(static)和寄存器(register),缺省类型为自动(auto)。

    而这里的数据类型则是和我们在第四课中学习到的名种数据类型的定义是一样的。说明了一个变量的数据类型后,还可选择说明该变量的存储器类型。存储器类型的说明就是指定该变量在C51硬件系统中所使用的存储区域,并在编译时准确的定位。表6-1中是KEIL uVision2所能认别的存储器类型。注意的是在AT89C51芯片中RAM只有低128位,位于80H到FFH的高128位则在52芯片中才有用,并和特殊寄存器地址重叠。特殊寄存器(SFR)的地址表请看附录二 AT89C51特殊功能寄存器列表

    存储器类型

    说 明

    data

    直接访问内部数据存储器(128字节),访问速度最快

    bdata

    可位寻址内部数据存储器(16字节),允许位与字节混合访问

    idata

    间接访问内部数据存储器(256字节),允许访问全部内部地址

    pdata

    分页访问外部数据存储器(256字节),用MOVX @Ri指令访问

    xdata

    外部数据存储器(64KB),用MOVX @DPTR指令访问

    code

    程序存储器(64KB),用MOVC @A+DPTR指令访问

    表6-1 存储器类型

    如果省略存储器类型,系统则会按编译模式SMALL,COMPACT或LARGE所规定的默认存储器类型去指定变量的存储区域。无论什么存储模式都可以声明变量在任何的8051存储区范围,然而把最常用的命令如循环计数器和队列索引放在内部数据区可以显著的提高系统性能。还有要指出的就是变量的存储种类与存储器类型是完全无关的。

    SMALL存储模式把所有函数变量和局部数据段放在8051系统的内部数据存储区这使访问数据非常快,但SMALL存储模式的地址空间受限。在写小型的应用程序时,变量和数据放在data内部数据存储器中是很好的因为访问速度快,但在较大的应用程序中data区最好只存放小的变量、数据或常用的变量(如循环计数、数据索引),而大的数据则放置在别的存储区域。

    COMPACT存储模式中所有的函数和程序变量和局部数据段定位在8051系统的外部数据存储区。外部数据存储区可有最多256字节(一页),在本模式中外部数据存储区的短地址用@R0/R1。

    LARGE存储模式所有函数和过程的变量和局部数据段都定位在8051系统的外部数据区外部数据区最多可有64KB,这要求用DPTR数据指针访问数据。

    之前提到简单提到sfr,sfr16,sbit定义变量的方法,下面我们再来仔细看看。

    sfr和sfr16可以直接对51单片机的特殊寄存器进行定义,定义方法如下:

    sfr 特殊功能寄存器名= 特殊功能寄存器地址常数;

    sfr16 特殊功能寄存器名= 特殊功能寄存器地址常数;

    我们可以这样定义AT89C51的P1口sfr P1 = 0x90; //定义P1 I/O口,其地址90H   sfr关键定后面是一个要定义的名字,可任意选取,但要符合标识符的命名规则,名字最好有一定的含义如P1口可以用P1为名,这样程序会变的好读好多。等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H-FFH),具体可查看附录中的相关表。sfr是定义8位的特殊功能寄存器而sfr16则是用来定义16位特殊功能寄存器,如8052的T2定时器,可以定义为:

    sfr16 T2 = 0xCC; //这里定义8052定时器2,地址为T2L=CCH,T2H=CDH

    用sfr16定义16位特殊功能寄存器时,等号后面是它的低位地址,高位地址一定要位于物理低位地址之上。注意的是不能用于定时器0和1的定义。

    sbit可定义可位寻址对象。如访问特殊功能寄存器中的某位。其实这样应用是经常要用的如要访问P1口中的第2个引脚P1.1。我们可以照以下的方法去定义:

    (1)sbit 位变量名=位地址

    sbit P1_1 = Ox91;

    这样是把位的绝对地址赋给位变量。同sfr一样sbit的位地址必须位于80H-FFH之间。

    (2)Sbit 位变量名=特殊功能寄存器名^位位置sft P1 = 0x90;

    sbit P1_1 = P1 ^ 1; //先定义一个特殊功能寄存器名再指定位变量名所在的位置当可寻址位位于特殊功能寄存器中时可采用这种方法

    (3)sbit 位变量名=字节地址^位位置

    sbit P1_1 = 0x90 ^ 1;   这种方法其实和2是一样的,只是把特殊功能寄存器的位址直接用常数表示。

    在C51存储器类型中提供有一个bdata的存储器类型,这个是指可位寻址的数据存储器,位于单片机的可位寻址区中,可以将要求可位录址的数据定义为bdata,如:

    unsigned char bdata ib; //在可位录址区定义ucsigned char类型的变量ib

    int bdata ab[2]; //在可位寻址区定义数组ab[2],这些也称为可寻址位对象

    sbit ib7=ib^7 //用关键字sbit定义位变量来独立访问可寻址位对象的其中一位

    sbit ab12=ab[1]^12;   操作符"^"后面的位位置的最大值取决于指定的基址类型,char0-7,int0-15,long0-31。

    下面我们用上一课的电路来实践一下这一课的知识。同样是做一下简单的跑马灯实验,项目名为RunLED2。程序如下:

    sfr P1 = 0x90; //这里没有使用预定义文件,

    sbit P1_0 = P1 ^ 0; //而是自己定义特殊寄存器

    sbit P1_7 = 0x90 ^ 7; //之前我们使用的预定义文件其实就是这个作用

    sbit P1_1 = 0x91; //这里分别定义P1端口和P10,P11,P17引脚

    void main(void)

    {

    unsigned int a;

    unsigned char b;

    do{

    for (a=0;a<50000;a++)

    P1_0 = 0; //点亮P1_0

    for (a=0;a<50000;a++)

    P1_7 = 0; //点亮P1_7

    for (b=0;b<255;b++)

    {

    for (a=0;a<10000;a++)

    P1 = b; //用b的值来做跑马灯的花样

    }

    P1 = 255; //熄灭P1上的LED

    for (b=0;b<255;b++)

    {

    for (a=0;a<10000;a++) //P1_1闪烁

    P1_1 = 0;

    for (a=0;a<10000;a++)

    P1_1 = 1;

    }

    }while(1);

    }

    转自:http://blog.sina.com.cn/s/blog_739afc250100vbpj.html

    展开全文
  • 静态全局变量 作用域仅限于变量被定义的文件中,其他文件即使用 extern 声明也没法 使用他。准确地说作用域是从定义之处开始,到文件结尾处结束,在定义之处前面的那些 代码行也不能使用它。想要使用就得在前面再...

    静态全局变量

    作用域仅限于变量被定义的文件中,其他文件即使用 extern 声明也没法使用他。准确地说作用域是从定义之处开始,到文件结尾处结束,在定义之处前面的那些代码行也不能使用它。想要使用就得在前面再加 extern ***。要想直接使用,很简单,直接在文件顶端定义不就得了。

    静态局部变量

    在函数体里面定义的,就只能在这个函数里用了,同一个文档中的其他函数也用不了。由于被 static 修饰的变量总是存在内存的静态区,所以即使这个函数运行结束,这个静态变量的值还是不会被销毁,函数下次使用时仍然能用到这个值。

    例子

    #include <stdio.h>
    
    static int j;
    
    void fun1(void){
    	static int i=0;
    	i++;
    	printf("i=%d\t",i);
    }
    void fun2(void){
    	j=0;
    	j++;
    	printf("j=%d\n",j);
    }
    
    int main(){
    	for( int k=0; k<10; k++){
    		fun1();
    		fun2();
    	}
    	return 0;
    }
    
    

    执行结果

    [root@localhost test]# ./static 
    i=1	j=1
    i=2	j=1
    i=3	j=1
    i=4	j=1
    i=5	j=1
    i=6	j=1
    i=7	j=1
    i=8	j=1
    i=9	j=1
    i=10j=1
    
    
    展开全文
  • c语言变量赋值,初始化

    千次阅读 2016-10-22 15:57:45
    1 全局变量, 和静态局部变量,未初始化时值默认为0.无论是数组还是变量,都是如此。 2 局部变量,初始值为随机值。 3 数组类局部变量,当被部分初始化时,未被初始化部分,值默认为0。 1.在C语言中,“初始化”和...
    数组变量为全局变量,或被部分初始化,均会出现这种情况。
    
    C语言中,变量在没有显式初始化时,区分变量类型,有如下几种情况:
    1 全局变量, 和静态局部变量,未初始化时值默认为0.无论是数组还是变量,都是如此。
    2 局部变量,初始值为随机值。
    

    3 数组类局部变量,当被部分初始化时,未被初始化部分,值默认为0。

    1.在C语言中,“初始化”和“赋值”是两个不同的概念。楼主问题中应该是“初始化”而非“赋值”
    int a = 0; 在声明一个变量的时候指定变量的值,这叫做初始化;
    int a; a = 2; 这叫做赋值。
    2.auto变量处于运行时堆栈。它的特点:在调用一个函数的过程中,这个函数内部的auto变量才存在,当这个函数调用结束时,这些变量所占用的内存即被收回。如果多次调用一个函数,这个函数内部的auto变量在内存中的地址是不确定的。由于auto变量在内存中的地址不是一成不变的,所以在程序开始前,编译器无法确定它们的值,并不对它们进行初始化。
    因此,auto变量未被初始化时,编译器也不知道你想要往这个变量里存什么,所以它的值是不确定的,毫无意义的,等着你在运行时给它进行赋值操作。
    3.如果不对一个数组(非全局的、非静态的)进行初始化,这个和上面的变量未初始化一样,编译器不知道你要做什么,所以懒得浪费时间对它们进行初始化。
    如果对一个数组进行部分初始化,形如:
    int a[10] = {1, 2, 3};
    未被初始化的部分a[3]~a[9]便会被编译器初始化为0。我的理解是,这是编译器认为你只关心数组a中前三个数的值,而后面的编译器为了让你省心就帮你初始化为0了,这时候编译器想“反正你都让我把前三个给填上了数,我也不怕麻烦了,后几个我给你填0吧”,于是编译器很大方地挥一挥衣袖把a[3]~a[9]填为0。
    但是:
    int a[10];
    a[0] = 1;
    a[1] = 2;
    a[2] = 3;
    这个时候a[3]~a[9]的值并不是0.因为这是运行时赋值,这个时候编译器已经下班了,所a[3]~a[9]中的值也是不确定的。 
    4.最后,再说一下全局变量和一个函数内部的静态局部变量,它们并不是存储在运行时堆栈,在程序运行过程中,它们的在内存中地址是确定的,所以编译器就把它们初始化为0。

    展开全文
  • C语言变量赋值问题总结

    千次阅读 多人点赞 2015-12-22 19:03:10
    全局,静态变量,一般默认为0;  局部变量在栈上,取决于此处原来的数据,如果不初始化的话;  动态变量在堆上. 正是如此 一般来说 全局变量、静态变量处于数据区,默认初始化为0 (如果指定初始值,则为指定...


    正是如此
    一般来说 全局变量、静态变量处于数据区,默认初始化为0 (如果指定初始值,则为指定的值)
    而局部变量处于堆栈区,其数值是随机的,即当时内存中的值。

    总体来说
    不要利用编译器的这种默认原则
    而是应当显示的指定
    必要的初始化不是笨拙
    而是规范
    展开全文
  • 最近看《C程序设计》第五版唐浩强著对静态局部变量有这样一段: > 对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的...
  • 一、静态变量(static) 一种是函数局部作用域,通常用于统计函数调用次数等。作用域局限于函数作用域内部,不晚于第一次调用的时候初始化。 另一种是文件局部作用域的,可以实现文件级别的数据封存。 static变量在...
  • 普通局部变量未赋值时,打印出来的是变量对应内存中以前的数据,(因为内存中的数据不能删除,只能覆盖,给变量赋值的过程就是覆盖数据的过程),而静态局部变量(用static修饰的变量,例如:static int i;...
  • 测试结果:在C语言中,全局变量和静态变量,如果没有赋初值,则默认初始值int,float,char,空指针 分别为0.0.0.'\0',0~~~~~~~除了全局变量和静态变量以外,其它变量如果没有赋初值,则默认初始值为 内存中的垃圾内容,对于...
  • 原文地址:C语言--静态变量和动态变量初始化区别作者:1234a 补充:c里等号的意义是分两种情况,一种是在表达式里, 而另一种是在变量声明中。 在变量声明中的等号不可以看作是赋值, 它只是初始化,也就是说它的...
  • 单片机c语言变量的定义和赋值

    千次阅读 2012-02-10 17:57:18
    存储种类有四种:自动(auto),外部(extern),静态(static)和寄存器(register),缺省类型为自动(auto)。  而这里的数据类型则是和我们在第四课中学习到的名种数据类型的定义是一样的。说明了一个变量的数据...
  • 找了很长时间他们的差别,但是答案都不是很理想。 于是自己写代码来测验这四种情况的差别。 外部变量的作用 ...//声明外部变量并予以赋值 int main() { text();//进入测试函数 } int text() {
  • static在C语言里面有两个作用,第一个是修饰变量,第二个是修饰函数。 1、static修饰变量 按照作用范围的不同,变量分为局部变量和全局变量。如果用static修饰变量,不论这个变量是全局的还是局部的都是存储在静态...
  • 全局变量、本地变量静态本地变量 全局变量的初始化发生在main函数之前,没有初始化的全局变量会得到0值,指针会得到NULL。 局部变量没有初始化,会出现一个乱七八糟的值。内存中有什么就得到了什么结果。全局...
  • 关于一般静态变量的规则同样适用于用户自定义的静态对象,而且它同样也 必须有初始化操作。但是,零赋值只对内建类型有效,用户自定义类型必须 用构造函数来初始化。 如果在定义一个静态对象时没有指定构造函数参数...
  • 任何一个变量和函数都有两个属性,1、数据类型(我们已经熟知) 2、数据的存储类别 有2种存储方式,有4种存储类别 ...static静态局部变量 1、第一次赋值有效,以后在调用时,直接使用上一次调用的
  • 对于有C基础的同学来说,学js是相当简单的,语法类似,这里主要列一下两者的异同,基本上记住了...1、js中的变量赋值时,除了基本类型以外,都是赋引用。 2、两者都有回调函数的概念,而且函数名就是回调变量名 ...
  • C语言变量的生命周期

    2020-12-17 19:13:43
    全局静态变量:定义一个全局变量并使用static关键字修饰时,这个变量就成了全局静态变量, 它的生命周期和全局变量一样,但是作用域被限制在定义文件内,无法使用extern来让其他源文件中使用它 静态局部变量:在函数内...
  • 全局变量与静态变量

    2019-10-05 01:33:56
    全局变量与静态变量 static 声明的变量在C语言中有两方面的特征:1.变量被放在程序的全局存储区中,这样在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。2.变量用static告知编译器...
  • 静态变量与全局变量的区别

    千次阅读 2017-08-12 18:38:18
    全局变量与静态变量static 声明的变量在C语言中有两方面的特征:1.变量被放在程序的全局存储区中,这样在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。2.变量用static告知编译器,...
  • 文章目录一、一切都是数据1、静态数据2、动态数据(临时数据)二、常量三、变量1、整数型、字符型、浮点型变量2、字符串变量3、变量的命名四、C语言的关键字五、变量的初始化1、整数型、字符型、浮点型变量初始化2、...
  • 全局变量 静态变量

    2011-12-14 16:03:17
    static 声明的变量C语言中有两方面的特征:  1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。  2)、变量用static告知编译器,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 497
精华内容 198
关键字:

c语言静态变量赋值

c语言 订阅