在 C/C++中 static 关键字详解

这篇具有很好参考价值的文章主要介绍了在 C/C++中 static 关键字详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

static是 C/C++中的关键字之一,是常见的函数与变量(C++中还包括类)的修饰符,它常被用来控制变量的存储方式和作用范围。 在众多高级语言中都有其作为关键字或函数出现,所以这也是应当被程序员熟知其各种含义的一个单词
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

我们知道在函数内部定义的变量,当程序执行到它的定义处时,编译器为它在栈上分配空间,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义为全局的变量,但定义一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅只受此函数控制)。static 关键字则可以很好的解决这个问题。
另外,在 C++ 中,需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时,可将其定义为静态数据。

c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

详见C/C++内存分布

如果static变量定义时未赋初值,编译时会自动将其赋值为0

C/C++ 中的 static

这里 static 作用主要影响着变量或函数的生命周期作用域,以及存储位置

1. 静态局部变量

定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的

当 static 修饰局部变量时:

 ● 变量的存储区域由变为静态常量区
 ● 变量的生命周期由局部调用结束变为程序运行结束
 ● 变量的作用域不变。

函数调用开辟栈帧,函数中的局部变量在栈上分配存储空间,当函数执行完毕,函数栈帧销毁,栈空间由系统回收
而在static修饰函数局部变量的时,其修饰的静态局部变量只执行初始化一次,延长了局部变量的生命周期,直到程序运行结束以后才释放,但不改变作用域。

下面用代码进行验证:

#include <stdio.h>

void fun()
{
	static int val = 0;   //static 修饰局部变量
	val++;
	printf("%d\n", val);
}
int main()
{
	for (int i = 0; i < 7; i++){
		fun();
	}
	return 0;
}

没有 static 时, 函数每调用一次, 变量就会进行一次初始化值为 0,
当由 static修饰时, 初始化语句只会被执行一次所以值会一直累加。
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

2. 静态全局变量

在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件。

static 修饰全局变量时:

 ● 变量的存储区域在全局数据区的静态常量区
 ● 变量的作用域由整个程序变为当前文件(extern声明也不行)
 ● 变量的生命周期不变。

一个全局变量被 static 修饰,使全局变量只能在定义变量的当前文件使用,不能在其余文件使用,即使 extern外部声明也不行。

原因: 属于文件作用域的声明在缺省的情况下为 external 链接属性, 如定义个全局变量int g_a = 1;, a的链接属性为external,而加上 static会修改变量的缺省链接属性,改为internal
声明了全局变量 g_a 和 g_b (具有 external 链接属性 )的其他源文件在使用这两个变量时实际访问的是生命与此处的这两个变量;但是 g_c 只能由这个源文件访问,因为链接属性为internal

int g_a = 1;
extern int g_b;
static int g_c;

代码验证:

// add.c
static int global_val = 27;   //static 修饰全局变量

//staticdemo1.c
extern global_val;

int main()
{
	printf("%d", global_val);
	return 0;
}

不用 static 修饰 global_val 时的结果
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试
而使用 static 修饰时,链接时就会出现链接错误无法执行。
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

全局变量 与 extren

 具有 extrenal 链接属性的实体在其他语言术语中称作全局实体(global entity ),所有源文件中的函数均可以访问它。只要变量并非声明与代码块或者函数定义内部,它在缺省的情况下链接属性即为 extrenal。如果一个变量声明在代码块内部,在它面前添加 extren 关键字将使它使它所引用的是全局变量而非局部变量。
  具有链接属性为 extrenal 的实体总是具有静态存储类型。 全局变量在程序开始执行前创建,并在整个执行过程中始终存在。从属于函数的局部变量在函数在函数开始执行时进行创建,在函数执行完毕后销毁,但用于执行函数的机器指令在程序生命周期内一直存在。

使用 extren 进行声明提高代码的可读性是良好的编程习惯。

3. static 修饰函数

函数的作用域与全局变量一样都是整个程序。

当 static 修饰函数时:

 ● 函数的作用域由整个程序变为当前文件(extern声明也不行)

一个函数被 static 修饰,使函数只能在定义的源文件使用,不能在其余文件使用,即使 extern外部声明也不行。(同static 修饰全局变量)

如果我们将函数声明为 static,就会把它的链接属性从external,改为internal,这样将使得其他源文件不能访问这个函数;对于函数而言,存储类型不是问题,因为代码总是存储在只读的代码区中。

// add.c
static int add(int a, int b)
{
	return a + b;
}

//staticdemo1.c
extern add(int a, int b);

int main()
{
	printf("%d", add(10, 20));
	return 0;
}

这里直接看结果:

没有 static 修饰:c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

static 修饰:报了与修饰全局变量时同样的链接错误。
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试




C++的 static 成员

 声明为static类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的 成员函数,称之为静态成员函数

注:静态成员无法在构造函数初始化列表初始化!!

c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

注:静态的成员变量一定要在类外进行初始化!!

const修饰的成员除外
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

class A
{
public :
	A(){   //构造函数
		_count++;
	}
	A(const A& y){
		_count++;
	}
	static int GetCount(){    //静态成员函数
		return _count;
	}
public:      
	int a;
	//静态成员变量--》在类中的是声明要在类外进行定义
	static int _count;  
	static const int sa = 99;
	const static int sb;
	static const int sc;
};

int A::_count = 0;   //静态变量 _count 定义
const int A::sb = 88;
const int A::sc = 77;

void TestA() {
	cout << A::GetCount() << endl;  // 类静态成员通过 类名::静态成员 来访问
	A a1, a2; 
	A a3(a1);
	cout << A::GetCount() << endl;
}
静态成员变量
  1. 静态成员变量必须在类外进行定义定义时不用加 static ,类中只是声明
    c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试
const修饰的成员除外

c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

  1. 静态成员变量为所有类对象所共享,并没有包含在具体的对象中。
    所以并不影响 sizeof() 大小

  2. 静态成员变量的访问: 类名::静态成员变量名 或 对象.静态成员变量名。

cout << A::_count << endl;
cout << a1._count << endl;

c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试
类的对象可以使用静态成员函数和非静态成员函数。

注:静态成员变量也受访问限定符(public、protected、private)的限制。 所以私有的仍要通过类成员函数接口来进行访问,可以在通过类中公有的成员函数进行访问,

cout << A::GetCount() << endl;

但这种方式调用获取静态成员变量必须由静态成员函数访问,不能通过类名来调用类的非静态成员函数,否则就会出错
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

类外初始化的值:
下面代码的输出结果是?
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

静态成员函数
  1. 静态成员函数没有隐藏的 this 指针,不能访问非静态成员(变量、 函数)!
    c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试
    因为静态成员函数没有隐藏的 this 指针所以也不能定义成const成员函数(const 本质就是修饰隐藏参数this )
    c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

  2. 静态成员函数不能调用非静态成员函数。
    c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试

  3. 非静态成员函数可以调用静态成员函数。

static void fun(){
		_count = 0;
	}
	int GetCount(){
		//cout << this << endl;    
		fun();
		return _count;
	}



总结:

(1) 静态成员变量使用前必须先初始化(在类外定义),如:int A::_count = 0;
(2) 静态成员变量为所有类对象所共享,也受访问限定符(public、protected、private)的限制
(3) 静态成员函不能调用非静态成员函数,非静态成员函数可以调用静态成员函数
(4) 静态成员函数没有隐藏的 this 指针
所以静态成员函数可以访问类的静态成员、不能访问类的非静态成员(静态成员函数如何访问非静态成员)
c++ static关键字,cpp,笔记,c语言,c语言,c++,经验分享,static,面试




文章内容随着对C++的深入学习还有待更加完善,欢迎大佬指正




参考:
书籍:《C和指针》
https://www.cnblogs.com/33debug/p/7223869.html
https://baike.baidu.com/item/%E9%9D%99%E6%80%81%E5%87%BD%E6%95%B0/5644260文章来源地址https://www.toymoban.com/news/detail-623299.html

到了这里,关于在 C/C++中 static 关键字详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言】静态关键字static的用法(详解)

     🎈个人主页:库库的里昂  🎐CSDN新晋作者  🎉欢迎 👍点赞✍评论⭐收藏  ✨收录专栏:C语言初阶  ✨其他专栏:代码小游戏  🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗 【前言】 不同于其他,他们都有多种用

    2024年02月14日
    浏览(34)
  • 【C语言】 Static关键字的用法和详解(太细了!!!)

    文章目录 目录 前言 一、static是什么 二、static的用法 1.修饰局部变量 2.修饰全局变量          3.修饰函数 总结   static在不同的语言中又有不同的使用方法,本文介绍的是static在 C语言 当中的用法。   static在C语言中是,中文直译过来是 “静态的” ,static在

    2023年04月14日
    浏览(34)
  • 详解const、static关键字

    目录   一、static 二、const 在c语言中: static是用来修饰变量和函数的         1.修饰局部变量——称为静态局部变量         2.修饰全局变量——称为静态全局变量         3.修饰函数——称为静态函数 有关内存相关知识补充: 程序的所有数据,也就是所有的

    2024年02月06日
    浏览(38)
  • 【C】static关键字详解

    static的汉语意思是静态的,在C语言中static可以用来修饰 局部变量、全局变量和函数。 在这里给大家补充一个知识,我们的数据在内存中存储时,大概分为3个区域。 1. 栈区 :我们创建的局部变量、形参等一般就存放在这个区域,离开作用域是会自动销毁,将空间还给

    2024年02月10日
    浏览(33)
  • 详解Java的static关键字

    不依赖于对象实例:静态方法不需要依赖于任何对象实例,因为它们与具体的对象实例无关联。这意味着在没有创建对象实例的情况下,就可以直接通过类名访问或调用静态方法。 可以访问静态成员:静态方法可以访问类的静态成员(静态字段和静态方法),但不能访问非静

    2024年02月05日
    浏览(39)
  • C++ -- 学习系列 static 关键字的使用

    static 是 C++ 中常用的,被 static 修饰的变量只会在 静态存储区 (常量数据也存放在这里) 被分配一次内存,生命周期与整个程序一样,随着程序的消亡而消亡。 1. 在文件中定义的 静态全局变量 2. 在函数中定义的静态变量 3. 类的静态成员变量 4. 静态类对象 5. 类的静

    2024年02月09日
    浏览(41)
  • 【C++】static 关键字的特性 与 问题

    声明为 static的类成员 称为 类的静态成员 用 static 修饰的成员变量 ,称之为 静态成员变量 ; 用 static 修饰的成员函数 ,称之为 静态成员函数 。 静态成员变量 一定要在 类外进行初始化 。 下面一段代码证明 上述定义: 输出结果: 从代码可以看出,静态成员变量需要在 类

    2024年02月14日
    浏览(33)
  • 在C++和C中static关键字的用法,在C++和C中const关键字的用法

    1、在C++和C中static的用法 答:static表示存储类型,修饰数据类型。在C语言中,static修饰局部变量,内存分配在静态区,生命周期延长,作用域不变。static修饰全局变量,内存分配在静态区,作用域被局限于本文件,不能被extern引用。static修饰函数,不能被exter

    2024年02月10日
    浏览(31)
  • 在 C/C++中 static 关键字详解

    static 是 C/C++中的 之一, 是常见的函数与变量(C++中还包括类)的修饰符 ,它常被用来控制变量的存储方式和作用范围。 在众多高级语言中都有其作为或函数出现,所以这也是应当被程序员熟知其各种含义的一个单词 我们知道在函数内部定义的变量,当程序执

    2024年02月14日
    浏览(27)
  • C++——初始化列表 | explicit关键字 | static成员

    🌸作者简介: 花想云 ,在读本科生一枚,致力于 C/C++、Linux 学习。 🌸 本文收录于 C++系列 ,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新! 🌸 相关专栏推荐: C语言初阶系列 、 C语言进阶系列 、 数据结构与算法 本章我们

    2023年04月11日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包