当前位置:首页 » 编程软件 » 静态局部变量对编译器影响

静态局部变量对编译器影响

发布时间: 2022-04-27 14:59:30

㈠ 静态变量与非静态变量的区别

1、存储位置不同

静态变量:存储在全局数据区(静态数据区)。

非静态变量叫动态变量:存储在内存出栈数据区。

2、生命期不同

动态变量:根据你定义的位置确定,比如你在一个函数中定义的,那么超出该函数范围变量将失效。

静态变量:程序结束时才释放。

3、作用域不同

动态变量:同样的要根据你定义的位置才能确定,和第二点的一样。

静态变量:当前文件中有效。

(1)静态局部变量对编译器影响扩展阅读;

静态变量的作用;

1、对于静态全局变量,源文件静态声明的文件级变量和函数的作用域仅限于文件(仅在文件中可见),即内部连接,因此可以用来限制变量的作用域。

2、对于静态局部变量,虽然函数内静态声明的变量范围与自动局部变量的范围相同(即范围仅在函数内),但存储空间是通过静态分配而不是默认的自动分配获得的。

所以存储空间在不同的区域是不同的(一般来说,静态分配时在编译时在程序数据段中划分存储空间,一次性分配在整个过程中是有效的。而在自动分配时,存储空间是在调用堆栈上分配的,只分配和释放在调用期间),两个调用之间的变量值总是一致的。必须注意,静态局部变量只能初始化一次,这是由编译器保证的。

3、对于静态成员变量,在C++中,类定义中静态声明的成员变量属于类变量,即它们在所有类实例中共享,相反是过程变量。

参考资料来源;网络——静态变量

网络——动态变量

㈡ 全局变量,静态全局变量,静态局部变量和局部变量的区别1

全局变量、静态全局变量、静态局部变量和局部变量的区别
变量可以分为:全局变量、静态全局变量、静态局部变量和局部变量。
按存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域,局部变量存放在内存的栈区。
按作用域分,全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数返回后失效。
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
全局变量和静态变量如果没有手工初始化,则由编译器初始化为0。局部变量的值不可知。

㈢ 假设一个顺序执行的C/C++源文件中,一个静态变量从某一位置起不再被使用了。那么编译器会不会,使该变量占

1.静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
2. 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。

㈣ 局部静态变量的引用问题。。。先谢谢啦!

保留字肯定就是关键字撒,
(1)auto
这个这个关键字用于声明变量的生存期为自动,即将不在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量。这个关键字不怎么多写,因为所有的变量默认就是auto的。

(2)register
这个关键字命令编译器尽可能的将变量存在CPU内部寄存器中而不是通过内存寻址访问以提高效率。

(3)static
常见的两种用途:
1>统计函数被调用的次数;
2>减少局部数组建立和赋值的开销.变量的建立和赋值是需要一定的处理器开销的,特别是数组等含有较多元素的存储类型。在一些含有较多的变量并且被经常调用的函数中,可以将一些数组声明为static类型,以减少建立或者初始化这些变量的开销.

详细说明:
1>、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
2>、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
3>当static用来修饰全局变量时,它就改变了全局变量的作用域,使其不能被别的程序extern,限制在了当前文件里,但是没有改变其存放位置,还是在全局静态储存区。

使用注意:
1>若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
2>若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
3>设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题(只要输入数据相同就应产生相同的输出)

(4)const
被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。它可以修饰函数的参数、返回值,甚至函数的定义体。
作用:
1>修饰输入参数
a.对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。
b.对于内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。
2>用const修饰函数的返回值
a.如果给以“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。
如对于: const char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();//cannot convert from 'const char *' to 'char *';
正确的用法是:
const char *str = GetString();
b.如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。 如不要把函数int GetInt(void) 写成const int GetInt(void)。
3>const成员函数的声明中,const关键字只能放在函数声明的尾部,表示该类成员不修改对象.

说明:
const type m; //修饰m为不可改变
示例:
typedef char * pStr; //新的类型pStr;
char string[4] = "abc";
const char *p1 = string;
p1++; //正确,上边修饰的是*p1,p1可变
const pStr p2 = string;
p2++; //错误,上边修饰的是p2,p2不可变,*p2可变
同理,const修饰指针时用此原则判断就不会混淆了。

const int *value; //*value不可变,value可变
int* const value; //value不可变,*value可变
const (int *) value; //(int *)是一种type,value不可变,*value可变
//逻辑上这样理解,编译不能通过,需要tydef int* NewType;
const int* const value;//*value,value都不可变

(5)volatile
表明某个变量的值可能在外部被改变,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。它可以适用于基础类型如:int,char,long......也适用于C的结构和C++的类。当对结构或者类对象使用volatile修饰的时候,结构或者类的所有成员都会被视为volatile.
该关键字在多线程环境下经常使用,因为在编写多线程的程序时,同一个变量可能被多个线程修改,而程序通过该变量同步各个线程。
简单示例:
DWORD __stdcall threadFunc(LPVOID signal)
{
int* intSignal=reinterpret_cast(signal);
*intSignal=2;
while(*intSignal!=1)
sleep(1000);
return 0;
}
该线程启动时将intSignal 置为2,然后循环等待直到intSignal 为1 时退出。显然intSignal的值必须在外部被改变,否则该线程不会退出。但是实际运行的时候该线程却不会退出,即使在外部将它的值改为1,看一下对应的伪汇编代码就明白了:
mov ax,signal
label:
if(ax!=1)
goto label
对于C编译器来说,它并不知道这个值会被其他线程修改。自然就把它cache在寄存器里面。C 编译器是没有线程概念的,这时候就需要用到volatile。volatile 的本意是指:这个值可能会在当前线程外部被改变。也就是说,我们要在threadFunc中的intSignal前面加上volatile关键字,这时候,编译器知道该变量的值会在外部改变,因此每次访问该变量时会重新读取,所作的循环变为如下面伪码所示:
label:
mov ax,signal
if(ax!=1)
goto label

注意:一个参数既可以是const同时是volatile,是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

(6)extern
extern 意为“外来的”···它的作用在于告诉编译器:有这个变量,它可能不存在当前的文件中,但它肯定要存在于工程中的某一个源文件中或者一个Dll的输出中。

参考

另外:c语言中的关键字
auto :声明自动变量 一般不使用
double :声明双精度变量或函数
int: 声明整型变量或函数
struct:声明结构体变量或函数
break:跳出当前循环
else :条件语句否定分支(与 if 连用)
long :声明长整型变量或函数
switch :用于开关语句
case:开关语句分支
enum :声明枚举类型
register:声明积存器变量
typedef:用以给数据类型取别名(当然还有其他作用)
char :声明字符型变量或函数
extern:声明变量是在其他文件正声明(也可以看做是引用变量)
return :子程序返回语句(可以带参数,也看不带参数)
union:声明联合数据类型
const :声明只读变量
float:声明浮点型变量或函数
short :声明短整型变量或函数
unsigned:声明无符号类型变量或函数
continue:结束当前循环,开始下一轮循环
for:一种循环语句(可意会不可言传)
signed:生命有符号类型变量或函数
void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)
default:开关语句中的“其他”分支
goto:无条件跳转语句
sizeof:计算数据类型长度
volatile:说明变量在程序执行中可被隐含地改变
do :循环语句的循环体
while :循环语句的循环条件
static :声明静态变量
if:条件语句

㈤ 静态局部变量和普通全局变量以及静态全局变量的区别

静态局部变量和普通全局变量以及静态全集变量在编译时,编译器会自动给他们分配地址。而且是从MCU上电运行开始,一直驻留,不会被回收的。

而真正的区别在于他们的作用域。
静态局部变量的作用域是在于定义它的那个函数内。由于其在编译时编译器就给他们分配了地址,并且做了初始化,所以它只能被初始化一次,而且看起来的顺序是程序每执行到这个函数时,都会执行那条定义语句,其实 并!没!有! 因为它已经被分配地址了,而且始终驻留在RAM中。而剥离这点,其他特性都与普通的局部变量相同。

普通全局变量,在本文件内可以被无限制地使用。而且其他的源文件中,也可以通过extern关键字引用后使用。

而静态全局变量则是在普通全局变量的基础上,取消了extern关键字引用,即无论怎么样,只能给本文件的程序使用,其他文件不能使用。(保护代码模块化,封闭外部接口)。

㈥ C语言——局部静态变量的问题

其实是这样的。静态变量在内存中存储的位置,与全局变量是同一个区域。
所以,在编译期间,它的存储和大小就已经确定了,也就是已经分配了空间了。
而在c语言中,“分配内存”往往看做是变量被定义的一个标志。
所以,你在运行程序的时候,由于静态变量已经分配过内存了,不会再次进行分配了,它的定义语句就不会再次被执行了。

㈦ C++成员函数中的静态局部变量能不能提高程序的执行效率

我想是可以提高效率的,静态局部变量只在第一次调用定义该局部静态变量的函数中初始化,在这之后即使重复调用该函数,该静态变量不再初始化,这可以节省下重新分配内存并初始化的开销。

㈧ <初级问题>static静态局部变量问题

加 static 则将原来的变量改为全局变量,在退出count函数时,
ctr并没有被销毁,所以++ctr时ctr值一直在增加,从而输出1-10

不加 static ,ctr为局部变量,在退出count函数时,ctr被销毁,所以每次的值都是1

实际上加 static 标识的局部变量,编译器会给被 static 标识的局部变量,分配独立的空间。从而实现局部变量全局化。

㈨ 静态变量和局部变量和全局变量的区别

1.从作用域看:
C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种:
全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。
1>全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern关键字再次声明这个全局变量。
2>静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。
3>局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
4>静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
2.从分配内存空间看:
1>全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间
2>全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
1)全局变量、静态全局变量以及静态局部变量都会被放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它们与堆变量、堆变量的区别。
2)静态变量(包括静态局部变量和静态全局变量)用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static这个说明符在不同的地方所起的作用是不同的。应予以注意。
Tips:
A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

热点内容
换编程题库 发布:2024-05-18 18:00:58 浏览:561
如何使用服务器ip直连网站 发布:2024-05-18 18:00:49 浏览:431
三星n7100哪个安卓版本好用 发布:2024-05-18 17:55:41 浏览:489
万国觉醒采集脚本源码 发布:2024-05-18 17:55:39 浏览:946
sqlserver加字段 发布:2024-05-18 17:54:53 浏览:927
安卓手机如何清除应用记录 发布:2024-05-18 17:31:37 浏览:639
查看存储过程权限 发布:2024-05-18 17:18:33 浏览:191
php类self 发布:2024-05-18 17:15:03 浏览:894
手机2b2t的服务器地址是多少 发布:2024-05-18 17:14:56 浏览:188
戴尔8490哪个配置比较合理 发布:2024-05-18 17:14:51 浏览:168