你知道嵌入式c中各变量存储位置吗
- 格式:doc
- 大小:19.50 KB
- 文档页数:3
C语言变量存储类别和内存四区C语言变量存储类别和内存四区C语言是一门通用计算机编程语言,应用广泛。
C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
下面我们一起来看看C语言变量存储类别和内存四区的介绍,欢迎大家阅读!C语言变量存储类别和内存四区变量存储类别变量声明/定义的一般形式:存储类别数据类型变量名存储类别指的是数据在内存中存储的方法。
存储方法分为静态存储和动态存储两大类。
标准C语言为变量、常量和函数定义了4种存储类型:extern、auto、static、register。
根据变量的存储类别,可以知道变量的作用域和存储期。
这4种存储类型可分为两种生存期限:永久的(在整个程序执行期都存在)和临时的(暂时保存在堆栈和寄存器中)。
extern和static用来标识永久生存期限的“变量和函数”,而anto和register用来标识临时生存期限的"变量"。
只有变量才有临时生存期限。
一个变量和函数只能具有一个存储类型,也只能有一种生存期限。
内存中供用户使用的空间有三部分:程序区:存放程序的可执行代码;静态存储区:存放静态变量(全局变量和静态局部变量);动态存储区:存放函数调用时调用函数的现场保护和返回地址、函数形参、自动局部变量;变量的声明分为”定义性声明“(需建立存储空间,如:int a;)和”引用性声明“(不需建立存储空间,如extern a;)。
广义上讲,声明包括定义,一般为叙述方便,把建立存储空间的声明称定义,而不不需建立存储空间的声明称声明。
auto函数中的局部变量,如果不用关键字static加以声明,编译系统对它们是动态地分配存储空间的。
函数的形参和在函数中定义的变量(包括在复合语句中定义的变量)都属此类。
在调用该函数时,系统给形参和函数中定义的变量分配存储空间,数据存储在动态存储区中。
在函数调用结束时就自动释放这些空间。
一、五大内存分区内存分成5个区,它们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
1、栈区(StaCk):FIFo就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。
里面的变量通常是局部变量、函数参数等。
2、堆区(heap):就是那些由new分配的内存块,它们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。
如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
3、自由存储区:就是那些由malloc等分配的内存块,它和堆是十分相似的,不过它是用free 来结束自己的生命。
4、全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
5、常量存储区:这是一块比较特殊的存储区,它们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)code/data/stack内存主要分为代码段,数据段和堆栈。
代码段放程序代码,属于只读内存。
数据段存放全局变量,静态变量,常量等,堆里存放自己malloc或new出来的变量,其他变量就存放在栈里,堆栈之间空间是有浮动的。
数据段的内存会到程序执行完才释放。
调用函数先找到函数的入口地址,然后计算给函数的形参和临时变量在栈里分配空间,拷贝实参的副本传给形参,然后进行压栈操作,函数执行完再进行弹栈操作。
字符常量一般放在数据段,而且相同的字符常量只会存一份。
二、C语言程序的存储区域1、由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段。
编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机器代码文件组合成一个文件。
2、C语言编写的程序经过编译-连接后,将形成一个统一文件,它由几个部分组成。
c语言函数参数存放标准
C语言函数参数的存放标准是按照栈的方式存放的。
栈是一种
后进先出的数据结构,函数参数在调用时会按照从右至左的顺序入栈。
具体来说,函数参数的存放顺序为:
1. 非首个参数依次入栈。
非首个参数的顺序是从右至左入栈,即最右边的参数先入栈。
2. 如果参数的类型占用4字节或更少的内存,则直接入栈;如果参数的类型占用更多的内存,则将参数的地址(指针)入栈。
这是因为函数参数的传递是通过值传递的方式,传递大于4字节的参数需要传递参数的地址。
3. 存放首个参数的位置取决于编译器的实现。
在某些编译器中,首个参数可能会存放在寄存器中,而不是入栈。
这种存放标准保证了函数在调用时能够正确地获取函数参数的值。
在函数体内部,通过访问入栈的参数,可以获取到对应的值进行计算和操作。
C语言中常见的变量在C语言中,变量是用来存储和操作数据的一种重要概念。
它们允许程序在运行时访问和修改内存中的值。
在本文中,我们将介绍C语言中常见的变量类型及其用法。
1. 整型变量(int)整型变量用于存储整数值。
在C语言中,整型变量可以是有符号(可以表示正负数)或无符号(仅表示非负数)。
常见的整型变量有:- int:用于表示有符号整数,通常占用4个字节。
- unsigned int:用于表示无符号整数,也占用4个字节。
- short:用于表示短整数,占用2个字节。
- unsigned short:用于表示无符号短整数,同样占用2个字节。
- long:用于表示长整数,占用4个字节或8个字节,具体取决于编译器和操作系统。
2. 浮点型变量(float和double)浮点型变量用于存储小数值。
在C语言中,浮点型变量可以是单精度(float)或双精度(double)。
常见的浮点型变量有:- float:用于表示单精度浮点数,通常占用4个字节。
- double:用于表示双精度浮点数,占用8个字节。
3. 字符型变量(char)字符型变量用于存储单个字符,如字母、数字或符号。
在C语言中,字符型变量被视为整数类型,每个字符对应一个ASCII码。
常见的字符型变量有:- char:用于表示单个字符,通常占用1个字节。
4. 指针型变量(pointer)指针型变量用于存储内存地址。
它们允许程序直接访问内存中的数据。
指针变量必须指定所指向数据的类型。
指针变量的声明方式为:类型 *变量名。
常见的指针型变量有:- int *:指向整型数据的指针。
- float *:指向浮点型数据的指针。
- char *:指向字符型数据的指针。
5. 数组变量(array)数组变量用于存储一系列相同类型的数据。
数组的元素可以通过索引进行访问。
在C语言中,数组的大小必须在声明时指定,并且不能改变。
数组变量的声明方式为:类型变量名[大小]。
常见的数组变量有:- int 数组名[大小]:用于存储整型数据的数组。
第4章变量的存储类型4.1 概述C语言中的变量具有两种属性:根据变量所持有数据的性质不同而分为各种数据类型;根据变量的存储方式不同而分为各种存储类型.变量的数据类型决定了该变量所占内存单元的大小及形式;变量的存储类型规定了该变量所在的存储区域,因而规定了该变量作用时间的长短,即寿命的长短,这种性质又称为"存在性".变量在程序中说明的位置决定了该变量的作用域,即在什么范围内可以引用该变量,"可引用"又称为"可见",所以这种性质又称为"可见性".计算机的内存和CPU中的寄存器都可以存放数据,变量究竟存放在何处则由存储类来决定.存储类型用来说明变量的作用域,生存期,可见性和存储方式.下面解释几个概念:1 作用域:是该变量在其上有定义的程序部分,通俗的说,即该变量起作用的某个程序区域。
2 变量的生存期:是指它从产生到消亡的存在时间,即变量从定义开始到它所占有的存储空间被系统收回为止的这段时间。
3 变量的可见性的含义:在某个程序区域,可以对变量进行访问(或称存取)操作,我们则称该变量在该区域为可见的,否则为不可见的。
再引入几个概念:4 全局变量和局部变量在一个函数内部或复合语句内部定义的变量叫内部变量,又称为"局部变量"。
在函数外定义的变量称为外部变量,又称为"全局变量"。
如:int x ;void main( ){int a, b;float c;……..}x 定义在函数外,是全局int 型变量a,b定义在main()函数内是局部int 型变量c 定义在main()函数内是局部float 型变量6 动态存储变量和静态存储变量。
在程序运行期间,所有的变量均需占有内存,有的是临时占用内存,有的是整个程序运行过程中从头到尾占用内存。
对于在程序运行期间根据需要进行临时性动态分配存储空间的变量称为"动态存储变量",对于在程序运行期间永久性占用内存的变量称为"静态存储变量".一个正在运行的程序可将其使用内存的情况分为如下三类(如下图):程序代码区: 程序的指令代码存放在程序代码区。
c语言存储数据的方式C语言是一种广泛应用于计算机科学领域的编程语言,它提供了多种存储数据的方式。
本文将介绍几种常见的C语言数据存储方式,包括变量、数组、结构体、枚举和指针。
1. 变量变量是C语言中最基本的数据存储方式。
通过声明变量可以为不同类型的数据分配内存空间,并可以对其进行读取和修改。
常见的变量类型包括整型、浮点型、字符型等。
例如,可以使用int型变量来存储整数,float型变量来存储浮点数,char型变量来存储字符。
2. 数组数组是一种按顺序存储相同类型数据的集合。
通过声明数组可以在内存中分配一块连续的空间来存储数据。
数组的元素可以通过索引访问,索引从0开始。
例如,可以使用int型数组来存储一组整数,float型数组来存储一组浮点数,char型数组来存储一组字符。
3. 结构体结构体是一种自定义的数据类型,可以将多个不同类型的数据组合在一起。
通过声明结构体可以定义一个包含多个成员的数据结构,并可以为每个成员分配内存空间。
结构体的成员可以通过.运算符来访问。
例如,可以使用struct关键字定义一个学生结构体,包含姓名、年龄和成绩等成员。
4. 枚举枚举是一种自定义的数据类型,用于定义一组相关的常量。
通过声明枚举可以为每个常量分配一个整数值,并可以使用这些常量来表示特定的状态或选项。
例如,可以使用enum关键字定义一个颜色枚举,包含红、绿、蓝等常量。
5. 指针指针是一种特殊的变量,用于存储内存地址。
通过声明指针可以指向其他变量或数据结构的内存地址,并可以通过解引用操作符*来访问指针所指向的值。
指针在C语言中常用于动态内存分配和函数传参等场景。
例如,可以使用int型指针来存储一个整数变量的内存地址,char型指针来存储一个字符数组的内存地址。
总结起来,C语言提供了多种灵活的数据存储方式,包括变量、数组、结构体、枚举和指针。
合理选择不同的数据存储方式可以根据实际需求来提高程序的效率和可读性。
在实际编程中,根据数据类型和数据结构的特点,选择合适的存储方式是非常重要的。
一.C语言中,从变量的作用域角度来分,可以分为全局变量和局部变量。
二.变量值存在的时间角度来分,可以分为静态存储方式和动态存储方式。
所谓静态存储方式是指在程序运行期间有系统分配固定的存储空间的方式。
而动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。
具体包含4种:自动的(auto),静态的(static),寄存器的(register),外部的(extern)。
1. 自动的(auto)在调用函数时系统会给他们分配存储空间,在函数调用结束时就自动释放这些存储空间,这类局部变量称为自动变量。
2. 静态的(static)为了满足局部变量的值在函数调用结束后不消失而且保留原值,既占用的存储单元不释放,就出现了静态的局部变量,用static来声明的局部变量。
局部变量的特点:(1)相对自动变量(即动态局部变量),在程序的运行期间都占用静态存储区,直到程序结束才释放该存储区。
(2)静态局部变量只是在程序编译时赋初值,以后每次调用时不再重新赋初值,而只是保留上次函数调用结束时的值。
动态局部变量编译时不赋初值,直到程序调用时才给变量赋值,每次调用都要赋初值。
(3)在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时会自动赋初值0或空字符。
而对动态局部变量,不赋初值则它的值是一个不确定的值,因为动态变量每次都要自动分配存储空间,存储空间的值是不固定的。
(4)静态局部变量在函数调用结束后不释放,但其他函数是不能调用的。
3.寄存器的(register)为了提高程序的执行效率,对一些运算频繁的变量定义为寄存器变量可以节省每次程序执行时的内存读取,大大节省了时间,提高了效率。
寄存器的一些特点:(1)寄存器变量的特点程序运行时分配寄存器存储空间,结束时释放。
这个特点限定了只能把局部自动变量和形式参数定义为寄存器变量。
(2)局部静态变量不能定义为寄存器变量。
4. 外部的(extern)外部变量是在函数的外部定义的全局变量,他的作用是从变量的定义初开始,到本程序文件的末尾。
各种类型的变量所需存储空间和能够存储的范围变量是程序中用来存储数据的容器。
在编程语言中,各种类型的变量具有不同的存储空间和存储范围。
1. 整数变量:整数变量用来存储整数值。
在大多数编程语言中,整数变量的存储空间由它的数据类型决定。
通常,整数类型可以是有符号或无符号的。
有符号整数在存储空间中使用一个位来表示符号,而无符号整数没有符号位。
整数类型的存储空间通常以字节为单位,范围可以从8位(1字节)到32位(4字节)或更多。
存储范围根据数据类型可以从-2^(n-1)到2^(n-1)-1,其中n表示位数。
2. 浮点数变量:浮点数变量用来存储小数值。
浮点数类型通常有单精度和双精度两种。
在大多数编程语言中,单精度浮点数的存储空间为4字节,而双精度浮点数的存储空间为8字节。
单精度浮点数的范围约为10^38,双精度浮点数的范围约为10^308。
3. 字符变量:字符变量用来存储单个字符。
在大多数编程语言中,字符变量的存储空间为1字节。
字符变量通常可以存储ASCII字符集、Unicode字符集或其他编码系统的字符。
存储范围取决于字符集的大小。
4. 布尔变量:布尔变量用来存储布尔值,即真或假。
在大多数编程语言中,布尔变量的存储空间为1字节,通常用0表示假,用1表示真。
5. 数组变量:数组变量用来存储一组相同类型的值。
存储空间取决于数组的大小和元素类型。
数组的存储范围与其元素类型的存储范围相同。
6. 结构体变量:结构体变量用来存储不同类型的值组成的复合数据。
结构体的存储空间取决于其成员变量的类型和数量。
需要注意的是,不同的编程语言可能对变量的存储空间和存储范围有所不同。
此外,某些编程语言提供了更多类型的变量,如枚举、指针等,它们具有特定的存储空间和范围。
因此,在选择变量类型时,需要根据具体的编程语言和需求来确定适当的变量类型。
你知道嵌入式C语言中各变量存储的位置吗?
在举行C/C++编程时,需要程序员对内存的了解比较精准。
常常需要操作的内存可分为以下几个类别:
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局
部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)—普通由程序员分配释放,若程序员不释放,程序
结束时可能由OS回收。
注重它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放
在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
4、文字常量区—常量字符串就是放在这里的。
5、程序代码区—存放函数体的二进制代码。
以下是一段实际解释的程序代码:这是一个前辈写的,十分具体。
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456在常量区,p3在栈上。
static int c =0;全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456放在常量区,编译器可能会将它与p3
第1页共3页。
C51变量的存储一、全局变量和局部变量全局变量和局部变量的区别在于作用域的不同。
此外还有静态全局变量和静态局部变量。
全局变量作用域为全局,在一个源文件中定义,其他的源文件也可以应用。
在其他的源文件中使用extern加以声明;静态全局变量作用域为该源文件,只作用在声明它的源文件中,通过static声明,这样即使在其他的源文件中有相同名称的变量也不相同;局部变量作用域为函数内部。
当函数被调用时,为其分配空间,函数调用完成后收回内存,销毁变量;局部静态变量作用域为局部,只被初始化一次,但是在后面它一直存在。
即使函数调用完成后也一直存在。
全局变量和局部变量都是要分配内存的,它们的区别只是在于作用域不同。
在C中,全局变量、静态全局变量及静态局部变量都在静态存储区,由于这些变量的生存周期较长,占有较多的内存但是由于已经分配好了内存,因此速度较快,而局部变量则在栈中分配空间。
在KeilC51中这是不同的。
二、C51中的全局变量和局部变量在51中程序ROM和数据RAM是严格分开的,特殊功能寄存器与片内数据存储器统一编址。
这与其他一般的微机不同。
51中内部的RAM有256字节,外部可寻址64KB,对于256字节,其中前128字节(00-7FH)又分为三部分:通用寄存器组、可位寻址区、用户RAM区;高128字节(7F-FF)为SFR。
上电复位后堆栈指针指向07H,在通用寄存器区,此时对战区占用1,2,3组寄存器,但是用户可自行将sp设置在30-7F。
C51编译器通过将变量定义为不同的类型,来区分不同的存储区,常用的变量类型有:data:片内RAM的低128字节bdata:可位寻址的片内RAM以上两种类型可以快速的存取数据,常用来放临时性的传递变量或使用频率较高的变量。
idata:整个片内RAM。
xdata:片外存储区(64KB),由于在对片外存储区操作时,需要先将数据移到片内,进行处理后再存储到片外,因此常用来存放不常用的变量,或收集待处理的数据,或存放要被发往另一台计算机的数据。
C语⾔中内存分布及程序运⾏中(BSS段、数据段、代码段、堆栈)BSS段:(bss segment)通常是指⽤来存放程序中未初始化的全局变量的⼀块内存区域。
BSS是英⽂Block Started by Symbol的简称。
BSS 段属于静态内存分配。
数据段:数据段(data segment)通常是指⽤来存放程序中已初始化的全局变量的⼀块内存区域。
数据段属于静态内存分配。
代码段:代码段(code segment/text segment)通常是指⽤来存放程序执⾏代码的⼀块内存区域。
这部分区域的⼤⼩在程序运⾏前就已经确定,并且内存区域通常属于只读 , 某些架构也允许代码段为可写,即允许修改程序。
在代码段中,也有可能包含⼀些只读的常数变量,例如字符串常量等。
程序段为程序代码在内存中的映射.⼀个程序可以在内存中多有个副本.堆(heap):堆是⽤于存放进程运⾏中被动态分配的内存段,它的⼤⼩并不固定,可动态扩张或缩减。
当进程调⽤malloc/free等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)/释放的内存从堆中被剔除(堆被缩减)栈(stack) :栈⼜称堆栈,存放程序的局部变量(但不包括static声明的变量, static 意味着在数据段中存放变量)。
除此以外,在函数被调⽤时,栈⽤来传递参数和返回值。
由于栈的先进先出特点,所以栈特别⽅便⽤来保存/恢复调⽤现场。
储动态内存分配,需要程序员⼿⼯分配,⼿⼯释放下图是APUE中的⼀个典型C内存空间分布图例如:#include <stdio.h>int g1=0, g2=0, g3=0;int max(int i){int m1=0,m2,m3=0,*p_max;static n1_max=0,n2_max,n3_max=0;p_max = (int*)malloc(10);printf("打印max程序地址\n");printf("in max: 0x%08x\n\n",max);printf("打印max传⼊参数地址\n");printf("in max: 0x%08x\n\n",&i);printf("打印max函数中静态变量地址\n");printf("0x%08x\n",&n1_max); //打印各本地变量的内存地址printf("0x%08x\n",&n2_max);printf("0x%08x\n\n",&n3_max);printf("打印max函数中局部变量地址\n");printf("0x%08x\n",&m1); //打印各本地变量的内存地址printf("0x%08x\n",&m2);printf("0x%08x\n\n",&m3);printf("打印max函数中malloc分配地址\n");printf("0x%08x\n\n",p_max); //打印各本地变量的内存地址if(i) return 1;else return 0;}int main(int argc, char **argv){static int s1=0, s2, s3=0;int v1=0, v2, v3=0;int *p;p = (int*)malloc(10);printf("打印各全局变量(已初始化)的内存地址\n");printf("0x%08x\n",&g1); //打印各全局变量的内存地址printf("0x%08x\n",&g2);printf("0x%08x\n\n",&g3);printf("======================\n");printf("打印程序初始程序main地址\n");printf("main: 0x%08x\n\n", main);printf("打印主参地址\n");printf("argv: 0x%08x\n\n",argv);printf("打印各静态变量的内存地址\n");printf("0x%08x\n",&s1); //打印各静态变量的内存地址printf("0x%08x\n",&s2);printf("0x%08x\n\n",&s3);printf("打印各局部变量的内存地址\n");printf("0x%08x\n",&v1); //打印各本地变量的内存地址printf("0x%08x\n",&v2);printf("0x%08x\n\n",&v3);printf("打印malloc分配的堆地址\n");printf("malloc: 0x%08x\n\n",p);printf("======================\n");max(v1);printf("======================\n");printf("打印⼦函数起始地址\n");printf("max: 0x%08x\n\n",max);return 0;}打印结果:可以⼤致查看整个程序在内存中的分配情况:可以看出,传⼊的参数,局部变量,都是在栈顶分布,随着⼦函数的增多⽽向下增长.函数的调⽤地址(函数运⾏代码),全局变量,静态变量都是在分配内存的低部存在,⽽malloc分配的堆则存在于这些内存之上,并向上⽣长.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~在操作系统中,⼀个进程就是处于执⾏期的程序(当然包括系统资源),实际上正在执⾏的程序代码的活标本。
c语言数据的四种存储类型-回复标题:C语言数据的四种存储类型详解在深入探讨C语言编程的世界中,数据存储类型是构建程序逻辑的基础元素之一。
它们定义了变量或函数在内存中的生命周期、作用域和可见性。
本文将详细解析C语言中的四种主要数据存储类型:自动存储类型、静态存储类型、寄存器存储类型以及外部存储类型。
1. 自动存储类型(Auto)自动变量是在函数内部声明的局部变量,其存储类型默认为“auto”,虽然在现代C语言中可以省略不写。
这类变量在执行到其声明处时分配空间,当控制权离开该函数时,即函数结束时,系统会自动释放其占用的内存空间,因此得名“自动”。
自动变量的作用域仅限于定义它的代码块内。
例如:cvoid func() {int autoVar; 这是一个自动变量...}在上述代码中,`autoVar` 在`func()` 函数体内声明,当`func()` 执行完毕后,`autoVar` 就不再存在。
2. 静态存储类型(Static)静态变量也是在函数内部声明,但与自动变量不同的是,它具有静态存储持续性,即即使函数结束,其值也不会丢失,下次调用函数时仍然保留上次的值。
此外,静态局部变量的作用域仍限制在声明它的函数内,但在整个程序运行期间始终占据内存空间。
例如:cvoid func() {static int staticVar = 0;staticVar++;printf("staticVar: d\n", staticVar);}每调用一次`func()`,`staticVar` 的值就会加一,因为其存储类型为静态。
3. 寄存器存储类型(Register)寄存器存储类型的变量请求编译器将其存储在CPU的寄存器中以提高访问速度,而非内存中。
然而,并非所有声明为register的变量都能真正被存放在寄存器中,这完全取决于硬件限制和编译器的优化策略。
寄存器变量也具有自动存储期限,即在其所在代码块结束时失效。
1.全局变量和局部变量全局变量为整个程序而定义,在整个程序运行期间,它们占用固定的RAM资源。
在C语言中,在所有函数外部声明的变量都认为具有全局作用域,这些声明通常置于源文件的顶部。
“全局”实际上仅仅意味着标识符从声明点到文件末尾的范围内是可访问的,当程序包含多个源文件时,则在一个文件中定义的全局变量在其他文件引用时,需要使用extern关键字声明。
在引用文件内部,标识符的作用域是由extern声明的位置确定的。
如果该声明是全局的,那么该标识符对于文件是全局的;如果该声明是放在块内的,则它对于那个块就是局部的。
局部变量为某个函数或子程序而定义,只在函数运行时,从堆栈空间中分配存储空间;函数运行结束,所占用堆栈空间释放。
2.变量修饰符变量定义有三个修饰符值得注意,虽然它们与标准C是相同的,但是在嵌入式C语言中又有不同的含义。
(1) volatile大多数编译器对源程序编译时做优化操作,其中一种优化方法是基于这种假设:除非明确地把某值写到内存,否则内存中的值不会改变。
所以如果源程序中频繁使用某个内存,编译器会把这个内存放到CPU寄存器或高速缓存中,提高代码运行速度。
在嵌入式系统中,这种优化会影响程序的正确执行,典型的情况是:①硬件外设寄存器的值随时都在变化,并且这种变化是不需要在写寄存器程序来改变。
②内存变量在主程序中没有显示改变,但在中断服务程序被改变,如果编译器在主程序中将内存以寄存器来取代,中断服务程序对变量的改变就不能传递到主程序中。
对于这两种情况做变量声明时,需要加前缀volatile,告诉编译器不要对这些变量做优化操作。
例如:volatile char device_status(2) static在子函数中用static声明的变量是局部变量,局部的范围可能是一个文件、函数、过程中,在局部的范围内,变量可以调用,变量值可以共享。
下面给出了一个子函数中使用的局部变量的用法。
void MyFunction (void){static char myVar = 0; //用static声明的局部变量myVar = myVar + 1;}void main (void){MyFunction(); //调用之前myVar = 0,调用之后myVar = 1MyFunction(); //调用之前myVar = 1,调用之后myVar = 2}(3) const修饰符const可以用在任何变量之前,用于声明变量值不会被改变,即“只读的”。
局部变量、全局变量、堆、堆栈、静态和全局变量一般全局变量存放在数据区,局部变量存放在栈区,动态变量存放在堆区,函数代码放在代码区。
---------------------------------------------------------------栈区是普通的栈数据结构,遵循LIFO后进先出的规则,局部变量安排在那里是ASM时就规定的,这样可以在一个函数结束后平衡堆栈,操作简单,效率高堆(动态区)在这里应当叫堆栈(不要和数据结构中的堆搞混)是程序在编译时产生的一块用于产生动态内存分配使用的块,操作比较栈要麻烦许多,在分配时要判断最优的地址(防止产生无用的内存碎片(由于屡次的NEW和DELETE产生的夹在两块使用中内存中的空余小内存(不容易被分配))),分配和回收时的效率比栈低多了---------------------------------------------------------------栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而堆是函数库提供的功能,特点是灵活方便,数据适应面广泛,但是效率>有一定降低。
栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。
不同堆分配的内存无法互相操作。
栈空间分静态分配和动态分配两种。
静态分配是编译器完成的,比如自动变量(auto)的分配。
动态分配由malloca函数完成。
栈的动态分配无需释放(是自动的),也就没有释放函数。
为可移植的程序起见,栈的动态分配操作是不被鼓励的!堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/ 释放内存匹>配是良好程序的基本要素。
堆是程序员管理的,栈是系统管理的.另外关于静态和全局的一些问题:静态变量的特点:1、一次存储:静态局部变量只被初始化一次,下一次初始化根据上一次的结果值,有点类似于c++中类的静态成员变量,即无论该类型生成多少个实例对象,所有的对象共用一个静态变量,到这里就是无论这个函数调用多少次,该静态变量只初始化一次,并没有因为超出其生存期而被销毁,只是外部不可见而已,用个例子说明之:void fun1( int v ){static int value = v;static int value = v;}int main( int arc, char*args[ ]){fun1( 50 );fun1( 100 );}执行的结果是:value : 50 value : 50说明在第二次调用fun1( )时的初始化value的采用的是上一次value的值,value在静态区的存储空间并没有因为fun1( )的结束而被释放,即体现了一次存储;2、作用域限定:静态修饰的作用域限定功能同时体现在函数与变量上;a)对于函数而言,任何用static修饰的函数,其作用域仅为当前源文件,而对外部来说这个函数是不可见的,即只有和其在同一源文件中的函数才能调用这个静态函数;反过来说,如果一个函数仅仅被同一源文件中的其他函数调用,那么这个函数应该声明为静态的,这样做的好处在于:可以一定程度上的解决不同源文件之间函数的命名冲突问题;b)对于变量而言,static修饰的全局变量,只在当前源文件中有效,对外部不可见,外部文件不能够引用;顾名思义,全局变量是指能够在全局引用的变量,相对于局部变量的概念,也叫外部变量;同静态变量一样,全局变量位于静态数据区,全局变量一处定义,多处引用,用关键字“extern”引用“外部”的变量。
C语言中变量储存的类别C语言中变量储存的类别C语言根据变量的生存周期来划分,可以划分为静态存储方式和动态存储方式。
C语言中变量储存的类别静态存储方式:是指在程序的运行期间分配固定的`存储空间的方式。
静态存储区中存储放了在整个程序执行过程中都存在的变量,如全局变量动态存储方式:是指在程序运行期间根据需要进行动态的分配存储空间的方式。
动态存储区中存放的变量是根据程序运行需要而进行的需要而建立和释放的。
通常包括: 1. 函数形式参数;2. 自动变量;3. 函数调用时的现场保护、4. 和返回值地址等。
C语言中的存储类别又分为4类:自动(auto)、静态(static)、动态(extern)寄存器(register)1、用关键字auto定义的变量为自动变量,auto可以省略,auto 不写则隐含定为”自动存储类别“,属于动态存储方式。
1 2 3 4 5int fn(int a)//定义f函数,a为参数{//定义b,c为自动变量auto int b,c;}2、用static修饰的为静态变量,如果定义在函数内部,称之为静态局部变量;如果定义在函数外部,称之为静态外部变量,1 2 3 4 5 6 #include <stdio.h>void fn(){static int x =0;x++;7 8 91011121314151617printf("fn: x=%d ",x);}int main(){int i;for(i=0;j<10;i++){fn();}return 0;}</stdio.h>注意:静态局部变量属于静态存储类别,在静态存储区内分配存储单元,在程序整个运行期间都不释放;静态局部变量在编译时赋初值,即只赋初值一次;如果在定义局部变量时,不赋初值的话,则对静态局部变量来说,编译时自动赋初值0.(对数值型变量)或空字符(对字符变量)。
3、为了提高效率,C语言允许将局部变量得值放在CPU中的寄存器中,这种变量叫”寄存器变量“,用关键字register做声明1 2 3 4 void fn(){register int i;}注意:只有局部自动变量和形式参数可以作为寄存器变量;一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量局部静态变量不能定义为寄存器变量。
C语⾔-常量和变量的存储位置C语⾔ - 常量和变量的存储位置⽬录〇、环境项值语⾔C编译器gcc编译环境x86_64-linux-gnu⼀、常量和变量的存储位置1.1 实验⽅法静态观察:对编译得到的可执⾏⽂件进⾏分析动态观察:运⾏时获取变量的地址,并分析变量在进程地址空间的位置1.2 ⽰例程序⽰例程序1#include <stdio.h>#include <unistd.h>static int local_static_uninit;static int local_static_init = 0x88;static int localarr_static_uninit[1024];static int localarr_static_init[1024] = {1,2,3};int global_uninit;int gloabl_init = 0x88;int globalarr_uninit[1024];int globalarr_init[1024] = {1,2,3};int add(int a, int b){static int infun_static_uninit;static int infun_static_init = 0x88;static int infunarr_static_uninit[1024];static int infunarr_static_init[1024] = {1,2,3};int c;int d = 0;int e = a + b;printf ("&local_static_uninit=%p\n""&local_static_init=%p\n""&localarr_static_uninit[0]=%p\n""&localarr_static_init[0]=%p\n""&global_uninit=%p\n""&gloabl_init=%p\n""&globalarr_uninit[0]=%p\n""&globalarr_init[0]=%p\n""&infun_static_uninit=%p\n""&infun_static_init=%p\n""&infunarr_static_uninit[0]=%p\n""&infunarr_static_init[0]=%p\n""&a=%p\n""&b=%p\n""&c=%p\n""&d=%p\n",&local_static_uninit,&local_static_init,&localarr_static_uninit[0],&localarr_static_init[0],&global_uninit,&gloabl_init,&globalarr_uninit[0],&globalarr_init[0],&infun_static_uninit,&infun_static_init,&infunarr_static_uninit[0],&infunarr_static_init[0],&a, &b, &c, &d);while (1){sleep (5);}return e;}int main(){add(1,2);return 0;}⽂件布局:运⾏输出:./a.out&local_static_uninit=0x6040e0&local_static_init=0x601060&localarr_static_uninit[0]=0x604100&localarr_static_init[0]=0x601080&global_uninit=0x606120&gloabl_init=0x602080&globalarr_uninit[0]=0x606140&globalarr_init[0]=0x6020a0&infun_static_uninit=0x605100&infun_static_init=0x6030a0&infunarr_static_uninit[0]=0x605120&infunarr_static_init[0]=0x6030c0&a=0x7ffd0ee30b1c&b=0x7ffd0ee30b18&c=0x7ffd0ee30b2c&d=0x7ffd0ee30b30进程地址布局:cat /proc/2446/maps00400000-00401000 r-xp 00000000 fc:00 130819 /home/ttt/test/a.out00600000-00601000 r--p 00000000 fc:00 130819 /home/ttt/test/a.out00601000-00605000 rw-p 00001000 fc:00 130819 /home/ttt/test/a.out00605000-00608000 rw-p 00000000 00:00 0007cf000-007f0000 rw-p 00000000 00:00 0 [heap]7f54a3458000-7f54a3618000 r-xp 00000000 fc:00 659982 /lib/x86_64-linux-gnu/libc-2.23.so 7f54a3618000-7f54a3818000 ---p 001c0000 fc:00 659982 /lib/x86_64-linux-gnu/libc-2.23.so 7f54a3818000-7f54a381c000 r--p 001c0000 fc:00 659982 /lib/x86_64-linux-gnu/libc-2.23.so 7f54a381c000-7f54a381e000 rw-p 001c4000 fc:00 659982 /lib/x86_64-linux-gnu/libc-2.23.so 7f54a381e000-7f54a3822000 rw-p 00000000 00:00 07f54a3822000-7f54a3848000 r-xp 00000000 fc:00 659993 /lib/x86_64-linux-gnu/ld-2.23.so 7f54a3a3c000-7f54a3a3f000 rw-p 00000000 00:00 07f54a3a47000-7f54a3a48000 r--p 00025000 fc:00 659993 /lib/x86_64-linux-gnu/ld-2.23.so 7f54a3a48000-7f54a3a49000 rw-p 00026000 fc:00 659993 /lib/x86_64-linux-gnu/ld-2.23.so 7f54a3a49000-7f54a3a4a000 rw-p 00000000 00:00 07ffd0ee11000-7ffd0ee32000 rw-p 00000000 00:00 0 [stack]7ffd0eff3000-7ffd0eff6000 r--p 00000000 00:00 0 [vvar]7ffd0eff6000-7ffd0eff8000 r-xp 00000000 00:00 0 [vdso]ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]1.3 结果分析1.3.1 运⾏时结果源⽂件中的全局变量,包括普通全局变量、静态全局变量,不论是否初始化,均在程序段(可写数据段)函数内部的静态变量,不论是否初始化,均在程序段(可写数据段)。
你知道嵌入式c中各变量存储位置吗
局部变量,局部静态变量,全局变量,全局静态变量区别:
局部变量:栈区
局部静态变量:静态区
全局变量:静态区的常量区
全局静态变量:静态区
在进行C++/C++编程时,需要程序员对内存的了解比较精准。
经常需要操作的内存可分为以下几个类别:
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS 回收。
注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
- 程序结束后有系统释放
4、文字常量区—常量字符串就是放在这里的。
程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。
以下是一段实际说明的程序代码:
这是一个前辈写的,非常详细
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈。