局部变量、全局变量、静态局部变量、静态全局变量的异同
static全局变量与普通的全局变量有什么区别
(1)用于全局变量:外部静态变量,只能在本源文件中被引用,不能被其它源文件所引用。
(2)用于局部变量:局部静态变量,在函数返回后存储单元不释放;下一次调用该函数时,该变量为上次函数返回时的值。
(3)用于函数:内部函数,只能被本源文件中的函数所调用,不能被其它源文件调用。
Static全局变量与普通的全局变量有什么区别:1.static全局变量只初使化一次,防止在其他文件单元中被引用;2.static局部变量只被初始化一次,下一次依据上一次结果值;3.static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝const关键字在C语言中用于声明”只读变量”,其值不可修改,但具有确定的数据类型。
C 编译器总是为其分配相应的存储单元。
在C++中,const关键字用于声明常量,C++编译器视具体情况决定是为其分配存储单元还是仅将其作为编译期间的常量。
在C++中,还可以修饰类的成员函数,不改变类中的数据成员.被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
char * const p; //常量指针,p的值不可以修改char const * p;//指向常量的指针,指向的常量值不可以改const char *p; //和char const *pASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。
如果表达式不为0,则继续执行后面的语句。
这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了就终止程序以免导致严重后果,同时也便于查找错误。
例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:const作用:修饰变量、修饰函数参数、修饰函数返回值三个作用。
被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
1)const变量有数据类型,而宏常量没有数据类型。
局部变量全局变量静态局部变量静态全局变量的异同
局部变量、全局变量、静态局部变量、静态全局变量的异同2011-01-18 10:16完成内容:1.收获备忘;2.局部变量、全局变量、静态局部变量、静态全局变量的异同;3.设计函数atoi()(字符串转int型)4.含参数的宏与函数的优缺点;一.收获备忘1.数组名指向的是一块内存块,内存的地址与大小在生命期内不可改变,只有内存块中的内容可以改变;指针可以随时指向任意类型的内存块;2.strcpy()函数的原型:char *strcpy(char *strDestination, const char *strSource);malloc()函数的原型:void *malloc(size_t size);free()函数的原型:void free(void *memblock);3.指针在free()或delete后,需重新指向NULL,或指向合法的内存;4.申请动态内存后,应该马上判断是否申请成功(malloc和new 申请动态内存不成功返回NULL),若申请不成功,则用exit(1)强制退出程序;5.内存分配的三种方式:(1).从静态存储区域分配:变量在编译时已经分配好,在整个程序运行期间都存在,例如:全局变量,静态全局变量;(2).从“栈”上分配:函数内的局部变量,在使用时自动从栈上创建内存区域,函数结束时自动释放。
由于栈上内存的分配运算内置于处理器的指令集中,使用效率很高,但容量有限;(3).从“堆”上分配:即动态内存分配,程序员可使用malloc ()/new申请任意大小的动态内存空间,同时由程序员决定何时使用free ()/delete去释放已申请的内存。
使用起来十分灵活,但最容易出问题;6. 指针参数传递内存的方法及常见错误P47-P49二.局部变量,全局变量,静态局部变量,静态全局变量的异同虽然之前在编程时对这四个“变量”就有不少困惑,但一直没去细究,前两天在联想的笔试题中看到了这样一道题,貌似知道它们的区别却又不能说出其中的原理,今天决定将其弄清楚。
变量和函数与静态动态局部和全局
计算机C语言核心知识点-变量和函数变量可以在程序中三个地方进行说明: 函数内部、函数的参数定义中或所有的函数外部。
根据所定义位置的不同, 变量可分为局部变量、形式参数和全局变量。
从空间角度来看,变量可以分为全局变量和局部变量,而从时间角度来分的可以有静态存储变量和动态存储变量之分。
一.全局变量和局部变量C语言中广泛使用局部变量来进行相关的存储的运算。
在一个函数模块中定义的变量成为局部变量,我们一般在进入函数的地方进行局部变量的定义,局部变量在定义的时候需要被赋予初始值,否则会是系统被分配的随机值。
局部变量的作用范围在函数体内部,每次进行函数的调用的时候,则进行局部变量的定义和分配内存单元。
也就是说随着被调用函数体的结束,局部变量会自动消失,内存空间会释放。
所以我们可以再不同的函数模块中去定义相同的局部变量。
他们之间互相不会影响,在执行完某个函数的时候,会释放相应的存储单元,其他的函数单元也能进行重新定义和开辟存储空间。
我们如果要使用函数体内部生成的布局变量的话,一般是通过静态变量来实现。
局部变量也称为内部变量。
局部变量是在函数内作定义说明的。
其作用域仅限于函数内部,离开该函数后再使用这种变量是非法的。
局部变量从存储方式上可分为动态(auto)存储类型和静态(static)存储类型。
动态存储类型的局部变量都是动态的分配存储空间,数据存储在动态存储区(栈)中。
函数调用结束后自动释放,生存期是在声明该变量的函数执行过程。
静态存储类型的局部变量则是静态的分配存储空间,数据存储在静态存储区中。
在程序整个运行期间都不释放,生存期贯穿于程序运行的整个过程。
函数中的局部变量,如不专门声明为static存储类别,默认都是动态地分配存储空间的,我们在平时的声明变量的过程中auto都是默认省略的。
C语言中也会广泛使用全局变量来进行运算。
全局变量也称为外部变量,是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。
c中static的作用和用法
一、static的基本概念二、static的作用1. 控制变量的作用域2. 保持变量的持久性3. 保护变量不被其他文件访问三、static的用法1. 在函数内部使用static修饰局部变量2. 在全局变量前使用static修饰3. 在函数前使用static修饰函数四、static与全局变量、局部变量以及extern的区别与通联五、static在不同编程语言中的应用情况六、总结一、static的基本概念在C语言中,static是一个重要的关键字,它可以用来修饰变量和函数,具有一定的特殊作用。
二、static的作用1. 控制变量的作用域当static修饰局部变量时,该变量的作用域仅限于声明它的函数内部,超出该函数范围后,该变量就无法被访问。
这种特性在一定程度上增强了函数的安全性和封装性,避免了变量被误用或意外修改的风险。
2. 保持变量的持久性一般情况下,局部变量的生命周期仅限于其所在的函数执行期间,函数执行完毕后,这些局部变量所占用的内存空间就会被回收。
但是,如果将局部变量使用static修饰后,它的生命周期将会被延长至整个程序的执行期间,即使函数执行完毕,该变量所占用的内存空间也不会被回收。
这种特性有利于在多次调用同一个函数时,保持上一次调用的状态信息。
3. 保护变量不被其他文件访问当static修饰全局变量时,该全局变量的作用范围会被限制在声明它的文件内部,其他文件无法直接访问该全局变量。
这为数据的封装和保护提供了可能。
三、static的用法1. 在函数内部使用static修饰局部变量```void function() {static int a = 0;// other statements}```2. 在全局变量前使用static修饰```static int b = 0;// other statements```3. 在函数前使用static修饰函数```static void function() {// function statements}```四、static与全局变量和局部变量以及extern的区别与通联1. static全局变量和普通全局变量的区别在于作用域不同。
静态变量,全局变量,局部变量的区别
For personal use only in study and research; not for commercial use静态变量,全局变量,局部变量的区别1.C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。
从作用域看:1>全局变量具有全局作用域。
全局变量只需在一个源文件中定义,就可以作用于所有的源文件。
当然,其他不包含全局变量定义的源文件需要用extern关键字再次声明这个全局变量。
2>静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
3>局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
4>静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static 关键字修饰过的变量具有文件作用域。
这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
2.从分配内存空间看:1>全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间2>全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。
这两者在存储方式上并无不同。
这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。
而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。
由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
CC++中static的用法全局变量与局部变量
CC++中static的⽤法全局变量与局部变量1.什么是static? static 是C/C++中很常⽤的修饰符,它被⽤来控制变量的存储⽅式和可见性。
1.1static的引⼊ 我们知道在函数内部定义的变量,当程序执⾏到它的定义处时,编译器为它在栈上分配空间,函数在栈上分配的空间在此函数执⾏结束时会释放掉,这样就产⽣了⼀个问题: 如果想将函数中此变量的值保存⾄下⼀次调⽤时,如何实现?最容易想到的⽅法是定义为全局的变量,但定义⼀个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不只受此函数控制)。
static关键字则可以很好的解决这个问题。
另外,在C++中,需要⼀个数据对象为整个类⽽⾮某个对象服务,同时⼜⼒求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时,可将其定义为静态数据。
1.2静态数据的存储 全局(静态)存储区:分为DATA段和BSS段。
DATA段(全局初始化区)存放初始化的全局变量和静态变量;BSS段(全局未初始化区)存放未初始化的全局变量和静态变量。
程序运⾏结束时⾃动释放。
其中BBS段在程序执⾏之前会被系统⾃动清0,所以未初始化的全局变量和静态变量在程序执⾏之前已经为0。
存储在静态数据区的变量会在程序刚开始运⾏时就完成初始化,也是唯⼀的⼀次初始化。
在C++中static的内部实现机制:静态数据成员要在程序⼀开始运⾏时就必须存在。
因为函数在程序运⾏中被调⽤,所以静态数据成员不能在任何函数内分配空间和初始化。
这样,它的空间分配有三个可能的地⽅,⼀是作为类的外部接⼝的头⽂件,那⾥有类声明;⼆是类定义的内部实现,那⾥有类的成员函数定义;三是应⽤程序的main()函数前的全局数据声明和定义处。
静态数据成员要实际地分配空间,故不能在类的声明中定义(只能声明数据成员)。
类声明只声明⼀个类的“尺⼨和规格”,并不进⾏实际的内存分配,所以在类声明中写成定义是错误的。
变量的作用域
变量的作用域⏹所有变量都有自己的作用域,即该变量的有效区域。
⏹按照变量的作用域,可分为:⏹局部变量(内部变量)⏹全局变量(外部变量)局部变量⏹指在一个函数内部定义的变量,它只在本函数的范围内有效,在此函数之外不能使用这些变量⏹说明:⏹main函数中定义的变量也是局部变量,只在main函数中有效⏹不同函数中同名变量,占不同内存单元,互不干扰⏹函数的形式参数也是局部变量⏹可在复合语句中定义变量,它们只在复合语句的内部有效⏹变量的定义必须在可执行语句之前,即进入{ }后,首先要定义变量全局变量⏹在所有函数之外定义的变量⏹它的有效范围从定义变量的位置开始到本源文件结束,一直占内存⏹如在定义时没初始化,系统自动初始化为0#include <stdio.h>int p=1 , q=5 ;float f1( int a ){ float r ;:全局变量s的有效范围全局变量p和q 的有效范围全局变量m和n 的有效范围a,r 等为局部变量局部变量和全局变量示例⏹全局变量的使用增加了函数间数据联系的渠道,由于在同一文件中的所有函数都能使用全局变量, 所以可以利用全局变量从函数中得到一个以上的返回值,而使用return只能返回一个值。
⏹例: 求某班成绩的平均分,最高分和最低分。
#include <stdio.h>float max=0, min=100 ;float average( int n );int main(void){ int m; float ave2 ;scanf(“%d”, &m);ave2 = average(m);printf(“%f,%f,%f\n”, ave2, max, min); return 0;} float average( int n){ int i; float s, ave1, sum=0;for(i=1; i<=n ; i++){ scanf(“%f”,&s);if (s>max) max = s;if (s<min) min = s;sum=sum+s;}ave1=sum/n;return (ave1);}全局变量的使用⏹建议不要过多的使用全局变量⏹全局变量在程序的执行过程中一直占用存储单元⏹它使函数的通用性降低⏹它会降低程序的清晰性⏹若全局变量与局部变量同名,则全局变量被屏蔽#include <stdio.h>printf("max=%d",max(a, b));运行结果:max=8#include <stdio.h>int x = 10;void f( ){ int x = 1; x = x + 1;printf(“x=%d\n”, x );}int main(void){ x = x + 1;printf(“x=%d\n”, x); f( );return 0;}运行结果:x=11x=2变量的存储方式⏹从变量的作用域(即从空间)角度来分,可分为局部变量、全局变量。
c语言中变量的存储类别
一.C语言中,从变量的作用域角度来分,可以分为全局变量和局部变量。
二.变量值存在的时间角度来分,可以分为静态存储方式和动态存储方式。
所谓静态存储方式是指在程序运行期间有系统分配固定的存储空间的方式。
而动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。
具体包含4种:自动的(auto),静态的(static),寄存器的(register),外部的(extern)。
1. 自动的(auto)在调用函数时系统会给他们分配存储空间,在函数调用结束时就自动释放这些存储空间,这类局部变量称为自动变量。
2. 静态的(static)为了满足局部变量的值在函数调用结束后不消失而且保留原值,既占用的存储单元不释放,就出现了静态的局部变量,用static来声明的局部变量。
局部变量的特点:(1)相对自动变量(即动态局部变量),在程序的运行期间都占用静态存储区,直到程序结束才释放该存储区。
(2)静态局部变量只是在程序编译时赋初值,以后每次调用时不再重新赋初值,而只是保留上次函数调用结束时的值。
动态局部变量编译时不赋初值,直到程序调用时才给变量赋值,每次调用都要赋初值。
(3)在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时会自动赋初值0或空字符。
而对动态局部变量,不赋初值则它的值是一个不确定的值,因为动态变量每次都要自动分配存储空间,存储空间的值是不固定的。
(4)静态局部变量在函数调用结束后不释放,但其他函数是不能调用的。
3.寄存器的(register)为了提高程序的执行效率,对一些运算频繁的变量定义为寄存器变量可以节省每次程序执行时的内存读取,大大节省了时间,提高了效率。
寄存器的一些特点:(1)寄存器变量的特点程序运行时分配寄存器存储空间,结束时释放。
这个特点限定了只能把局部自动变量和形式参数定义为寄存器变量。
(2)局部静态变量不能定义为寄存器变量。
4. 外部的(extern)外部变量是在函数的外部定义的全局变量,他的作用是从变量的定义初开始,到本程序文件的末尾。
全局变量、局部变量、静态全局变量、静态局部变量的区别
全局变量、局部变量、静态全局变量、静态局部变量的区别⼀、C++变量根据定义的位置的不同的⽣命周期,具有不同的作⽤域,作⽤域可分为6种:全局作⽤域,局部作⽤域,语句作⽤域,类作⽤域,命名空间作⽤域和⽂件作⽤域。
(1)从作⽤域看:1、全局变量具有全局作⽤域。
全局变量只需在⼀个源⽂件中定义,就可以作⽤于所有的源⽂件。
当然,其他不包含全局变量定义的源⽂件需要⽤extern 关键字再次声明这个全局变量。
2、静态局部变量具有局部作⽤域,它只被初始化⼀次,⾃从第⼀次被初始化直到程序运⾏结束都⼀直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,⽽静态局部变量只对定义⾃⼰的函数体始终可见。
3、局部变量也只有局部作⽤域,它是⾃动对象(auto),它在程序运⾏期间不是⼀直存在,⽽是只在函数执⾏期间存在,函数的⼀次调⽤执⾏结束后,变量被撤销,其所占⽤的内存也被收回。
4、静态全局变量也具有全局作⽤域,它与全局变量的区别在于如果程序包含多个⽂件的话,它作⽤于定义它的⽂件⾥,不能作⽤到其它⽂件⾥,即被static关键字修饰过的变量具有⽂件作⽤域。
这样即使两个不同的源⽂件都定义了相同名字的静态全局变量,它们也是不同的变量。
(2)从分配内存空间看:1、全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,⽽局部变量在栈⾥分配空间2、全局变量本⾝就是静态存储⽅式,静态全局变量当然也是静态存储⽅式。
这两者在存储⽅式上并⽆不同。
这两者的区别虽在于⾮静态全局变量的作⽤域是整个源程序,当⼀个源程序由多个源⽂件组成时,⾮静态的全局变量在各个源⽂件中都是有效的。
⽽静态全局变量则限制了其作⽤域,即只在定义该变量的源⽂件内有效,在同⼀源程序的其它源⽂件中不能使⽤它。
由于静态全局变量的作⽤域局限于⼀个源⽂件内,只能为该源⽂件内的函数公⽤,因此可以避免在其它源⽂件中引起错误。
1)静态变量会被放在程序的静态数据存储区(全局可见)中,这样可以在下⼀次调⽤的时候还可以保持原来的赋值。
Java成员变量、局部变量、静态变量、成员方法、全局方法等概念的区别
Java成员变量、局部变量、静态变量、成员方法、全局方法等概念的区别在Java中,一个类体由2部分构成:一部分是变量的定义;一部分是方法的定义(一个类中可以有多个方法)Java中的变量可以分为成员变量,全局变量成员变量和局部变量的区别成员变量:(类似于C中的全局变量的概念,所以也可以说是全局变量)①成员变量定义在类中,在整个类中都可以被访问。
②成员变量随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。
③成员变量有默认初始化值。
局部变量:①局部变量只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。
②局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放。
③局部变量没有默认初始化值在使用变量时需要遵循的原则为:就近原则首先在局部范围找,有就使用;接着在成员位置找。
静态变量(也叫做类变量,类属性)由static修饰的变量称为静态变量,其实质上就是一个全局变量。
如果某个内容是被所有对象所共享,那么该内容就应该用静态修饰;没有被静态修饰的内容,其实是属于对象的特殊描述。
成员变量和静态变量的区别1、两个变量的生命周期不同成员变量随着对象的创建而存在,随着对象被回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2、调用方式不同成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3、别名不同成员变量也称为实例变量。
静态变量也称为类变量。
4、数据存储位置不同成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
列表对比:[java] view plain copyclass Demo{int x;// 非静态成员变量,又称为属性,对该类不同的对象来说,属性是不同的static int y;// 静态成员变量,一个类中只有一个该变量,该类不同的对象共享同一个静态成员变量public static void main(String[] args){int m = 0;// 局部变量,是方法内部定义的变量,只在方法内部可见,在该方法结束后,由垃圾回收器自动回收}}Java中的方法可以分为成员方法,全局方法,构造方法[java] view plain copypublic class Test {private int age; //这是成员变量public Test(int age) { //这是构造方法this.age = age;}public void setAge(int age) { //这是成员方法this.age = age;}public static int getAge() { //这是全局方法,加了static关键字,成员方法就变成了全局方法return this.age;}}成员方法必须用类的实例化对象进行访问,而全局方法是直接可以用类名.方法名来访问的,构造方法则是实例化对象时进行初始化的。
全局变量和局部变量
C语言的变量一、全局变量和局部变量按照变量的有效作用范围可划分为局部变量和全局变量。
局部变量是在一个函数内部定义的变量,该变量只在定义它的那个函数范围以内有效,在此函数之外局部变量就失去意义了,因而也不能使用这些变量了。
不同的函数可以使用相同的局部变量名,由于他们的作用范围不同,不会相互干扰。
函数的形式参数也属于局部变量。
在一个函数内部的复合语句中也可以定义局部变量,该局部变量只在该复合语句中有效。
全局变量是在函数外部定义的变量,又称外部变量。
全局变量可以为多个函数共同使用,其有效的作用范围是从它定义的位置开始到整个程序文件结束为止。
如果全局变量定义在一个程序文件的开始处,则在整个程序文件范围内都可以使用它。
如果一个全局变量不是在程序文件的开始处定义的,但又希望在它的定义点之前的函数中引用该变量,这时应该在引用该变量的函数中用关键字extern将其说明为“外部变量”。
另外,如果在一个程序模块文件中引用另一个程序模块文件中定义的变量时,也必须用extern进行说明。
外部变量说明与外部变量定义是不同的。
外部变量定义只能有一次,定义的位置在所有函数之外,而同一个程序文件中的外部变量说明可以有多次,说明的位置在需要引用该变量的函数之内。
外部变量说明的作用只是声明该变量是一个已经在外部定义过了的变量而已。
如果在同一个程序文件中,全局变量与局部变量同名,则在局部变量的有效作用范围之内,全局变量是不起作用的,也就是说,局部变量的优先级比全局变量的高。
在编写C语言程序时,不是特别需要的地方就不要使用全局变量,二应当尽可能的使用局部变量。
这是因为局部变量只有在使用它时,才为其分配内存单元,二全局变量在整个程序的执行过程中都要占用内存单元。
另外,如果使用全局变量过多,在各个函数执行时都有可能改变全局变量的值,使人们难以清楚的判断出在各个程序执行点处全局变量的值,这样会降低程序的通用性和可读性。
还有一点需要说明,如果程序中的全局变量在定义时赋给了初值,按ANSI C标准规定,在程序进入主函数之前必须先对该全局变量进行初始化。
局部变量,局部静态变量,全局变量,全局静态变量分别教学内容
局部变量,局部静态变量,全局变量,全局静态变量分别c++内存到底分几个区?一:1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由os回收。
注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
- 程序结束后有系统释放。
4、文字常量区—常量字符串就是放在这里的。
程序结束后由系统释放。
5、程序代码区—存放函数体的二进制代码。
二:1、栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。
里面的变量通常是局部变量、函数参数等。
2、堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。
如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
3、自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
4、全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的c语言中,全局变量又分为初始化的和未初始化的,在c++里面没有这个区分了,他们共同占用同一块内存区。
5、常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。
三:1、bss是英文block started by symbol的简称,通常是指用来存放程序中未初始化的全局变量的一块内存区域,在程序载入时由内核清0。
bss段属于静态内存分配。
它的初始值也是由用户自己定义的连接定位文件所确定,用户应该将它定义在可读写的ram区内,源程序中使用malloc分配的内存就是这一块,它不是根据data大小确定,主要由程序中同时分配内存最大值所确定,不过如果超出了范围,也就是分配失败,可以等空间释放之后再分配。
C语言中的各种变量
C语言中的各种变量C语言是一种应用广泛的善于实现控制的语言,变量在C语言中的应用更是灵活多变。
那么变量究竟是什么呢?变量是内存或寄存器中用一个标识符命名的存储单元,可以用来存储一个特定类型的数据,并且数据的值在程序运行过程中可以进行修改。
可见,变量首先是一个标识符或者名称,就像一个客房的编号一样,有了这个编号我们在交流中就可方便言表,否则,我们只可意会,那多不方便。
为了方便,我们在给变量命名时,最好能符合大多数人的习惯,基本可以望名知义,便于交流和维护;其次,变量是唯一确定的对应内存若干存储单元或者某个寄存器。
这些是编译器来保证的,用户一般不用费心。
程序员一旦定义了变量,那么,变量就至少可为我们提供两个信息:一是变量的地址,即就是,操作系统为变量在内存中分配的若干内存的首地址;二是变量的值,也就是,变量在内存中所分配的那些内存单元中所存放的数据。
由于程序的多样需要,我们对变量也有各种各样的要求,比如:变量的生命期,变量的初始状态,变量的有效区域,变量的开辟地和变量的开辟区域的大小等等;为了满足这些要求,C语言的发明者就设置了以下变量:1.不同数据类型的变量;如:char cHar, int iTimes, flaot faverage;2.全局变量或者叫全程变量;3.局部变量;4.静态变量:静态全局变量和静态局部变量;关键词:static静态变量是分配在存储器中C程序所占据的数据段内, C程序运行的整个过程中一直保留,不会被别的变量占用。
静态变量可以定义成全局变量或局部变量,当定义为全局变量时,在它定义的程序的整个运行期间均存在并且保持原来的存储单元位置不会改变。
5.寄存器变量;关键词:register;寄存器变量不像其他变量那样在内存中存放数据,而是在CPU的寄存器中暂存数据,使用寄存器变量比使用内存变量的操作速度快得多。
只有整型和字符型变量可定义为寄存器变量。
定义方式为register int iTemp;由于CPU中寄存器有限,尽量减少使用数量和和占用时间,用完马上释放;不能定义为全局变量,也不能定义在结构或者类中。
静态变量与全局变量的区别
静态变量与全局变量的区别全局变量与静态变量static 声明的变量在C语⾔中有两⽅⾯的特征:1.变量被放在程序的全局存储区中,这样在下⼀次调⽤的时候还可以保持原来的赋值。
这⼀点是它与堆栈变量和堆变量的区别。
2.变量⽤static告知编译器,⾃⼰仅在变量的作⽤范围内可见。
这⼀点是它与全局变量的区别。
Tips:A.若全局变量仅在单个C⽂件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;C.设计和使⽤访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重⼊问题;D.如果我们需要⼀个可重⼊的函数,那么,我们⼀定要避免函数中使⽤static变量(这样的函数被称为:带“内部存储器”功能的的函数)E.函数中必须要使⽤static变量的情况:⽐如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
函数前加static使得函数成为静态函数。
但此处“static”的含义不是指存储⽅式,⽽是指对函数的作⽤域仅局限于本⽂件(所以⼜称内部函数)。
使⽤内部函数的好处是:不同的⼈编写不同的函数时,不⽤担⼼⾃⼰定义的函数,是否会与其它⽂件中的函数同名。
扩展分析:术语static有着不寻常的历史。
起初,在C中引⼊关键字static是为了表⽰退出⼀个块后仍然存在的局部变量。
随后,static在C中有了第⼆种含义:⽤来表⽰不能被其它⽂件访问的全局变量和函数。
最后,C++重⽤了这个关键字,并赋予它与前⾯不同的第三种含义:表⽰属于⼀个类⽽不是属于此类的任何特定对象的变量和函数(与Java中此关键字的含义相同)。
全局变量、静态全局变量、静态局部变量和局部变量的区别变量可以分为:全局变量、静态全局变量、静态局部变量和局部变量。
按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。
c语言局部变量静态局部变量全局变量与静态全局变量
c语⾔局部变量静态局部变量全局变量与静态全局变量基本概念:作⽤域:起作⽤的区域,也就是可以⼯作的范围。
代码块:所谓代码块,就是⽤{}括起来的⼀段代码。
数据段:数据段存的是数,像全局变量就是存在数据段的代码段:存的是程序代码,⼀般是只读的。
栈(stack):先进后出。
C语⾔中局部变量就分配在栈中。
局部变量 普通的局部变量定义的时候直接定义或者在前⾯加上autovoid func1(void){int i = 1;i++;printf("i = %d.\n", i);}局部变量i的解析:在连续三次调⽤func1中,每次调⽤时,在进⼊函数func1后都会创造⼀个新的变量i,并且给它赋初值1,然后i++时加到2,然后printf输出时输出2.然后func1本次调⽤结束,结束时同时杀死本次创造的这个i。
这就是局部变量i的整个⽣命周期。
下次再调⽤该函数func1时,⼜会重新创造⼀个i,经历整个程序运算,最终在函数运⾏完退出时再次被杀死。
静态局部变量(static)静态局部变量定义时前⾯加static关键字。
总结:1、静态局部变量和普通局部变量不同。
静态局部变量也是定义在函数内部的,静态局部变量定义时前⾯要加static关键字来标识,静态局部变量所在的函数在多调⽤多次时,只有第⼀次才经历变量定义和初始化,以后多次在调⽤时不再定义和初始化,⽽是维持之前上⼀次调⽤时执⾏后这个变量的值。
本次接着来使⽤。
2、静态局部变量在第⼀次函数被调⽤时创造并初始化,但在函数退出时它不死亡,⽽是保持其值等待函数下⼀次被调⽤。
下次调⽤时不再重新创造和初始化该变量,⽽是直接⽤上⼀次留下的值为基础来进⾏操作。
3、静态局部变量的这种特性,和全局变量⾮常类似。
它们的相同点是都创造和初始化⼀次,以后调⽤时值保持上次的不变。
不同点在于作⽤域不同全局变量定义在函数外⾯的变量,就叫全局变量。
普通全局变量普通全局变量就是平时使⽤的,定义前不加任何修饰词。
全局变量与局部变量在内存中的区别详细解析
全局变量与局部变量在内存中的区别详细解析— 由编译器⾃动分配释放,存放函数的参数值,局部变量的值等。
其操作⽅式类似于数据结构中的栈。
— ⼀般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
注意它与数据结构中的堆是两回事,分配⽅式倒是类似于链表。
—,全局变量和静态变量的存储是放在⼀块的,初始化的全局变量和静态变量在⼀块区域(.data),未初始化的全局变量和未初始化的静态变量在相邻的另⼀块区域(.bss)。
- 程序结束后由系统释放。
—常量字符串就是放在这⾥的(.rodata)。
程序结束后由系统释放。
—存放函数体的⼆进制代码(.text)。
这是⼀个前辈写的,⾮常详细复制代码代码如下://main.cppint a = 0; // 全局初始化区char *p1; // 全局未初始化区main(){int b; // 栈区char s[] = "abc"; // 栈区char *p2; // 栈区char *p3 = "123456"; // "123456/0" 在常量区,p3在栈区static int c =0; // 全局(静态)初始化区p1 = (char *)malloc(10);p2 = (char *)malloc(20); // 分配得来的10和20字节的区域就在堆区strcpy(p1, "123456"); // "123456/0" 放在常量区,编译器可能会将它// 与p3所指向的"123456"优化成⼀个地⽅。
}static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。
全局变量本⾝就是静态存储⽅式,静态全局变量当然也是静态存储⽅式。
局部变量、全局变量、堆、堆栈、静态和全局变量
局部变量、全局变量、堆、堆栈、静态和全局变量一般全局变量存放在数据区,局部变量存放在栈区,动态变量存放在堆区,函数代码放在代码区。
---------------------------------------------------------------栈区是普通的栈数据结构,遵循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”引用“外部”的变量。
PHPstatic局部静态变量和全局静态变量总结
PHPstatic局部静态变量和全局静态变量总结1.不会随着函数的调⽤和退出⽽发⽣变化,不过,尽管该变量还继续存在,但不能使⽤它。
倘若再次调⽤定义它的函数时,它⼜可继续使⽤,⽽且保存了前次被调⽤后留下的值2.静态局部变量只会初始化⼀次3.静态属性只能被初始化为⼀个字符值或⼀个常量,不能使⽤表达式。
即使局部静态变量定义时没有赋初值,系统会⾃动赋初值0(对数值型变量)或空字符(对字符变量);静态变量的初始值为0。
4.当多次调⽤⼀个函数且要求在调⽤之间保留某些变量的值时,可考虑采⽤静态局部变量。
虽然⽤全局变量也可以达到上述⽬的,但全局变量有时会造成意外的副作⽤,因此仍以采⽤局部静态变量为宜。
复制代码代码如下:function test(){static $var = 5; //static $var = 1+1;就会报错$var++;echo $var . ' ';}test(); //2test(); //3test(); //4echo $var; //报错:Notice: Undefined variable: var复制代码代码如下://全局变量本⾝就是静态存储⽅式,所有的全局变量都是静态变量function static_global(){global $glo;$glo++;echo $glo.'<br>';}static_global(); //1static_global(); //2static_global(); //3echo $glo . '<br>'; //3所以静态全局变量使⽤并不多。
C++静态变量,常量的存储位置你真的了解吗
C++静态变量,常量的存储位置你真的了解吗⽬录引⾔C++对内存的划分如何落实在Linux上⾃由存储区和堆之间的问题栈常量区静态存储区静态局部变量静态局部变量、静态全局变量、全局变量的异同总结引⾔在动态内存的博客中,我提到:在Linux 内存管理的博客中,我提到:尽管都有尽可能完全的描述,并且两者⼤致意思没有冲突。
⽽之所以令我⼀直感到略有不同,越看越迷糊的原因是:第⼀张图讲的其实是C++在概念上对内存的划分,第⼆张图讲的是Linux对虚拟内存进⾏的划分。
前者是概念上的,也是C++程序在运⾏时会切实执⾏的,⽽后者就是在Linux系统上对前者概念的具象化!下⾯进⾏进⼀步分析。
C++对内存的划分如何落实在Linux上C++其实将内存划分为两种:动态存储区、静态存储区。
第⼀张图对动态存储区进⾏了进⼀步划分——堆、栈。
⽽⽹上其他博客可能还会对动态存储区进⾏进⼀步划分——堆、栈、⾃由存储区。
并对静态存储区进⾏进⼀步划分——常量存储区、全局/静态存储区。
可谓是五花⼋门,我们不妨先做个归拢:⾃由存储区和堆之间的问题这篇博客分析地很详细C++ ⾃由存储区是否等价于堆?,我引⽤其中⼀些内容进⾏分析:在概念上我们是这样区分两者的:malloc 在堆上分配的内存块,使⽤ free 释放内存。
new 所申请的内存则是在⾃由存储区上,使⽤ delete 来释放。
那么物理上,⾃由存储区与堆是两块不同的内存区域吗?它们有可能相同吗?基本上,所有的 C++编译器默认使⽤堆来实现⾃由存储,也即是缺省的全局运算符 new 和 delete 也许会按照 malloc 和 free 的⽅式来被实现,这时藉由 new 运算符分配的对象,说它在堆上也对,说它在⾃由存储区上也正确。
但程序员也可以通过重载操作符,改⽤其他内存来实现⾃由存储,例如全局变量做的对象池,这时⾃由存储区就区别于堆了。
总结:⾃由存储是 C++ 中通过 new 与 delete 动态分配和释放对象的抽象概念,⽽堆(heap)是 C语⾔和操作系统的术语,是操作系统维护的⼀块动态分配内存。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
局部变量、全局变量、静态局部变量、静态全局变量的异同
2011-01-18 10:16
完成内容:
1.收获备忘;
2.局部变量、全局变量、静态局部变量、静态全局变量的异同;
3.设计函数atoi()(字符串转int型)
4.含参数的宏与函数的优缺点;
一.收获备忘
1.数组名指向的是一块内存块,内存的地址与大小在生命期内不可改变,只有内存块中的内容可以改变;指针可以随时指向任意类型的内存块;
2.strcpy()函数的原型:char *strcpy(char *strDestination, const char
*strSource);
malloc()函数的原型:void *malloc(size_t size);
free()函数的原型:void free(void *memblock);
3.指针在free()或delete后,需重新指向NULL,或指向合法的内存;
4.申请动态内存后,应该马上判断是否申请成功(malloc和new申请动态内存不成功返回NULL),若申请不成功,则用exit(1)强制退出程序;
5.内存分配的三种方式:
(1).从静态存储区域分配:变量在编译时已经分配好,在整个程序运行期间都存在,例如:全局变量,静态全局变量;
(2).从“栈”上分配:函数内的局部变量,在使用时自动从栈上创建内存区域,函数结束时自动释放。
由于栈上内存的分配运算内置于处理器的指令集中,使用效率很高,但容量有限;
(3).从“堆”上分配:即动态内存分配,程序员可使用malloc ()/new申请任意大小的动态内存空间,同时由程序员决定何时使用free ()/delete去释放已申请的内存。
使用起来十分灵活,但最容易出问题;
6. 指针参数传递内存的方法及常见错误P47-P49
二.局部变量,全局变量,静态局部变量,静态全局变量的异同
虽然之前在编程时对这四个“变量”就有不少困惑,但一直没去细究,前两天在联想的笔试题中看到了这样一道题,貌似知道它们的区别却又不能说出其中的原理,今天决定将其弄清楚。
局部变量:在一个函数中或复合语句中定义的变量,在动态存储区分配存储单元,在调用时动态分配,在函数或复合语句结束时自动释放;
静态局部变量:在一个函数中定义局部变量时,若加上static声明,则此变量为静态局部变量,在静态存储区分配存储单元,在程序运行期间都不释放;静态局部变量只能在该函数中使用;静态局部变量在编译时赋值(若在定义时未进行赋值处理,则默认赋值为0(对数值型变量)或空字符(对字符型变量));静态局部变量在函数调用结束后不自动释放,保留函数调用结束后的值;
全局变量:在函数外定义的变量称为全局变量;全局变量在静态存储区分配存储单元,在程序运行期间都不释放,在文件中的函数均可调用该全局变量,其他文件内的函数调用全局变量,需加extern声明;
静态全局变量:在函数外定义变量时,若加上static声明,则此变量为静态全局变量;静态全局变量在静态存储区分配存储单元,在程序运行期间都不释放,静态全局变量在编译时赋值(若在定义时未进行赋值处理,则默认赋值为0(对数值型变量)或空字符(对字符型变量));只能在当前文件中使用;
参考谭浩强的《C程序设计第二版》P180,可从三个方面对以上四种变量进行区分:
1.从作用域角度分,有局部变量和全局变量:
局部变量
自动变量(auto变量,函数结束后释放)
静态局部变量(函数结束后值保留)
全局变量
静态外部变量(只限本文件中使用)
外部变量(允许其他文件引用)
2.从变量的生存期分,有动态存储和静态存储两种,动态存储即在调用函数时临时分配单元,静态存储则是程序整个运行时间内都存在。
动态存储
形式参数(本函数内有效)
auto自动变量(本函数内有效)
register寄存器变量(本函数有效)
静态存储
静态局部变量(本函数内有效)
静态外部变量(本文件中有效)
外部变量(允许其他文件引用)
3.从变量的储存位置分
内存中静态存储区
静态局部变量
静态外部变量
外部变量
内存中动态存储区
auto自动变量和形式参数
CPU中的寄存器
寄存器变量
三.设计函数int *atoi(const char *str);在联想的笔试题中看到这个题目,特意拿来练练手;程序代码如下:
#include <stdio.h>
#include <assert.h> //使用断言
#include <ctype.h> //使用isspace()、isdigit()函数的头文件
#include <math.h>
#define INT_MAX (int)((pow(2, sizeof(int) * 8)) / 2.0 - 1)
#include <stdio.h>
#include <assert.h> //使用断言
#include <ctype.h> //使用isspace()、isdigit()函数的头文件
#include <math.h>
#define INT_MAX (int)((pow(2, sizeof(int) * 8)) / 2.0 - 1)
int myatoi(const char *string)
{
int flag = 1;
int result = 0;
assert(string != NULL); //若string指向NULL,则判断非法调用myatoi()函数
//若字符串有空格或制表符,则跳过;
while (isspace(*string))
{
string++;
//获取字符串的'+','-'符号位;
if (*string=='+' || *string=='-')
{
flag = (*string == '-') ? -1 : 1;
string++;
}
//程序到这里,已经没有空格和'+','-'号了,若接下来的字符是数字, //则计算出数字的大小,若不是数字,则不计算,result依旧为0;
while (*string!='\0' && isdigit(*string))
{
result = 10 * result + (*string++ - '0');
}
//判断最后结果是否溢出,若溢出则退出程序
if ((unsigned)result > INT_MAX)
{
printf("The Number Input is larger than INT_MAX:%d\n", INT_MAX); printf("exit!\n");
exit(1);
}
return (result * flag);
}
int main(void)
{
printf("%d\n", myatoi(" +1234"));
printf("%d\n", myatoi(" -2147483647"));
printf("%d\n", myatoi(" 1234"));
printf("%d\n", myatoi(" adf 1234"));
}
此函数中
1.首先通过断言assert判断对myatoi()的调用是否合法;
2.判断字符串开头是否有空格或制表符(TAB),有则跳过;
3.若字符串第一个有效字符为’-‘,则flag置-1,若为’+’,则flag置1,若为其他字符,则判断此字符串为非数字字符串,result的最终值为0;
4.将字符类型的数字转换成int类型的数字,
5.判断result是否越界,若越界,跳出程序,否则返回result*flag的值;
这道题主要考的是程序员的编程风格,虽说这个函数看上去很简单,但如果要考虑到程序的健壮性,正确定,可靠性,效率,易用性,可扩展性,可移植性等属性的话,程序编写起来就不简单了;
四.含参数的宏与函数的优缺点
无参的宏就用得多了,但带参数的宏呢?见过很多,但真正自己去编的几乎没有,
今天,顺带把这个问题也搞清楚。
含参数的宏优点:
省去了函数调用的开销,运行效率高.
含参数的缺点:
由于宏本质上是字符串的替换,所有可能会由于一些参数的副作用导致得出
错误的结果.
如:
#define max(a, b) ( ((a) > (b)) ? (a) : (b) )
如果程序中出现这样的调用: max(a++, b);
将导致a被计算2次,从而可能得到错误的结果,而函数调用不会出现这种问题.另外,如果程序中有多次宏替换的话,可能导致代码体积变大.
函数调用的优点:
没有带参数宏可能导致的副作用,计算的正确性较宏更有保证.
函数调用的缺点:
函数调用需要一些参数,返回地址等入栈,出栈的开销,效率没有带参数的宏高.。