首页 > 编程知识 正文

c语言静态函数的声明和定义,c语言静态变量和全局变量的区别

时间:2023-05-03 20:06:09 阅读:166655 作者:2852

转了转写的比较详细的博客。 C一直不知道静态变量的问题,这次认真分析了。

这次主要关注全局变量。 由于全局变量分为全局和静态全局,其中全局变量可以在多个源文件中使用,因此不建议使用。 静态全局变量只能在当前源文件中使用,可以更好地保护数据。

我来是为了正文:

C语言需要用于存储数据的存储器。 存储器主要分为静态存储区和动态存储区两大类;

1 .静态存储

分为只读数据(READONLY DATA )区域、读写数据(RW DATA )区域、未初始化区域(BSS )。 所有这些都是在程序编译连接阶段决定的,在程序执行阶段不变。

2 .动态存储

分为堆和堆。 它们都是在程序运行过程中动态分配的,大小也是动态变化的。 从实现内存管理的角度来看,堆是使用链表实现的,而堆栈使用线性存储方法。

堆栈:堆栈是先进的后一种,在实际操作中,堆栈内存可能有完全堆栈和空堆栈,对于完全堆栈,如果堆栈指针的当前座位是已在使用的堆栈区域空堆栈,则为堆栈指针的当前位

满栈时:进入栈是先移动指针,放入数据的栈先弹出数据,然后移动指针;

空堆栈时:进入堆栈是先放入数据,然后移动指针。 堆栈正在先移动指针,发出数据。

C语言中必须注意的几个问题:

1 .内存泄漏:申请了一块内存,但没有释放,程序结束后也没有回收,其他程序无法使用

2 .野指针:指的是一个存储器指针已经释放了free或realloc,但指针仍在使用。 避免野生指针的情况,将内存的指针设为NULL,在程序使用时判断该内存是否为NULL,如果为空,则认为该内存已被释放,不访问内存。

3 .非法释放内存:原则上,只有分配给malloc (、calloc )或realloc )并由返回值返回的内存才会被释放。 否则,释放其他内存是不正当的。 *即使存在p为malloc的指针,对于p1=p,此时free(p(p1 )不合法,但free (p )确实是可能的。 同样,释放函数中的局部变量也是违法的。 另一种情况是,对一个堆内存释放两次也是错误的用法。 因为free ()函数无法释放未分配的堆内存。 在程序使用free释放内存后,必须将指针设置为NULL。 free的空地址没有问题。

在介绍之前,先介绍堆、堆栈、自由存储区、全局/静态存储区和常量存储区

堆:用new分配,free释放

自由内存区域: malloc分配,删除

堆栈:编译器管理的局部变量和函数参数等。

全局/静态存储区:存储静态变量和全局变量

字符常数区域:常数存储的存储器

也就是说,static限定函数的意思只是告诉编译器,我是内部函数,不要随便使用。

1 .静态变量

静态变量的类型说明符是静态的。 静态变量当然属于静态存储方式,但属于静态存储方式的量不一定是静态变量。 例如,外部变量是静态存储方法,但不一定是静态变量。 要称为静态外部变量或静态全局变量,必须在静态中定义。

2 .静态局部变量

静态局部变量是一种静态存储方法,具有以下特点:

)1)静态局部变量在函数内定义整个源程序的生存期,但作用域仍然与自动变量相同,只能在定义变量的函数内使用。 退出函数后,变量仍然存在,但不能使用。

)2)允许给结构系统的静态局部量赋予初始值,例如数组,如果没有赋予初始值,系统自动赋予0的值。

)3)基本型的静态局部变量,如果在说明时没有被赋予初始值,则自动被赋予0的值。 如果不为自动变量分配初始值,则该值不稳定。 根据静态局部变量的特点,可以看出生存期是整个源程序的量。 离开定义的函数后无法使用,但如果再次调用定义的函数,则可以继续使用。 它还保存上次调用后剩下的值。 因此,如果多次调用函数,并且需要在调用之间保留特定变量的值,请考虑采用静态局部变量。 虽然全局变量也可以达到上述目的,但建议使用局部静态变量,因为全局变量可能会引起意外的副作用。

3 .静态全局变量

在说明全局变量(外部变量)之前冠上静态就构成了静态全局变量。 全局变量本身是静态存储方法,静态全局变量当然也是静态存储方法。 两种保存方法都没有区别。 不同之处在于,非静态全局变量的范围是整个源程序,但如果一个源程序由多个源文件组成,则非静态全局变量在每个源文件中有效。 静态全局变量限制范围。 这意味着它只在定义变量的源文件中有效,不能在同一源程序的其他源文件中使用。 静态全局变量的范围限定在一个源文件中,并且仅适用于该源文件中的函数,从而避免在其他源文件中出现错误。 以上分析表明,将局部变量改为静态变量后,改变了保存方法,即改变了生存期。 将全局变量转换为静态变量会改变作用域,从而限制使用范围。 因此,static这个说明子所起的作用因地点而异。

4 .静态函数… .

当内部函数和外部函数:一个源程序由多个源文件构成时,c语言根据是否用另一个源文件的函数调用该函数,将该函数分成内部函数和外部函数。

(1)内部函数(也称为静态函数) ) )

如果在一个人的话

个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示:
static  函数类型  函数名(函数参数表)
{……}
关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。
2 外部函数
外部函数的定义:在定义函数时,如果没有加关键字“static”,或冠以关键字“extern”,表示此函数是外部函数:
[extern]  函数类型  函数名(函数参数表)
{……}
调用外部函数时,需要对其进行说明:
[extern]  函数类型  函数名(参数类型表)[,函数名2(参数类型表2)……];
[案例]外部函数应用。
(1)文件mainf.c
main()
{  <strong>extern void input(…),process(…),output(…);</strong>
<p style="color: #000000;"><strong>    </strong>input(…);  process(…);  output(…);
<p style="color: #000000;">    }
<p style="color: #000000;">(2)文件subf1.c
……
extern  void input(……)                           /*定义外部函数*/
{……}</p>
<p style="color: #000000;">(3)文件subf2.c
……
extern  void process(……)                     /*定义外部 函数*/
{……}
(4)文件subf3.c
……
extern void output(……)                        /*定义外部函数*/
{……}
C++中的静态成员变量和静态成员函数
(1)类静态数据成员在编译时创建并初始化:在该类的任何对象建立之前就存在,不属于任何对象,而非静态类成员变量则是属于对象所有的。类静态数据成员只有一个拷贝,为所有此类的对象所共享。特别需要注意的一点是:静态数据成员不能在类中初始化(对于常量静态类变量有待考证,好像可以在类外或main()函数之前定义,初始化可以放在类中),一般在类外和main()函数之前初始化,缺省时初始化为0。静态数据成员用来定义类的各个对象所公有的数据,比全局变量更安全。
(2)类静态成员函数属于整个类,不属于某个对象,由该类所有对象共享。静态成员可定义为inline函数。一般情况下静态成员函数用于访问同一类中的静态数据成员或全局变量,而不访问非静态成员,如需访问非静态成员,需要将对象作为参数,通过对象名访问该对象的非静态成员。静态成员函数也可以在类外定义,此时不可以用static修饰。静态成员函数存在的原因是什么呢?主要是在建立任何对象之前可用它来访问静态数据成员,普通函数不能实现此功能。
C++静态成员和静态成员函数的使用:静态成员的调用格式:类名::静态数据成员名、对象名.静态数据成员名、对象指针-&gt;静态数据成员、对象引用.静态数据成员(但类中很少会出现公有数据成员,这段仅仅讨论语法,未考虑实际运用中的数据封装问题)。静态成员函数的调用格式:类名::静态成员函数名、对象名.静态成员函数名、对象指针-&gt;静态成员函数名、对象引用.静态数据成员。静态成员函数没有this指针,因它不与特定对象相联系,调用时推荐使用“类名::静态成员函数名”格式。总结来说,在有对象的情况下,可以用调用普通类成员函数、普通成员变量的方式调用静态成员函数和静态成员变量。从这里可以看出静态成员变量和静态成员函数的使用应该是在不建立任何对象的情况下调用它们。其应用可以参见设计模式中Singleton pattern。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。