c/c++中static的用法

概述

static:
作为c/c++的关键字之一,具有多种含义和应用,static 关键字可用于声明变量、函数、类数据成员和类函数。默认情况下,在所有块的外部定义的对象或变量具有静态持续时间和外部链接。 静态持续时间意味着,在程序启动时分配对象或变量,并在程序结束时释放对象或变量。 外部链接意味着,变量的名称在用于声明变量的文件的外部是可见的。 相反,内部链接意味着,名称在用于声明变量的文件的外部是不可见的。

在以下情况下,可使用 static 关键字:

  1. 在文件范围(全局和/或命名空间范围)内声明变量或函数时,static 关键字将指定变量或函数具有内部链接。 在声明变量时,变量具有静态持续时间,并且除非您指定另一个值,否则编译器会将变量初始化为 0。

  2. 在函数中声明变量时,static 关键字将指定变量将在对该函数的调用中保持其状态。

  3. 在类声明中声明数据成员时,static 关键字将指定类的所有实例共享该成员的一个副本。 必须在文件范围内定义静态数据成员。 声明为 const static 的整型数据成员可以有初始值设定项。

  4. 在类声明中声明成员函数时,static 关键字将指定类的所有实例共享该函数。 由于函数没有隐式 this 指针,因此静态成员函数不能访问实例成员。 若要访问实例成员,请使用作为实例指针或引用的参数来声明函数。

  5. 不能将联合成员声明为静态的。 但是,全局声明的匿名联合必须是显式声明的 static。

静态全局变量

全局变量:
在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,应该做全局变量说明。只有在函数内经过说明的全局变量才能使用。但在一个函数之前定义的全局变量,在该函数内使用可以不再加以说明。
静态全局变量:
定义在函数体外,用来修饰全局变量,未经初始化的静态全局变量会被自动初始化为0;在申明静态全局变量的文件以外是不可见的。不同的源文件中都可以使用同一个全局变量,但当定义为静态全局变量之后,其作用域知存在于当前源文件。

举例:
变量maxstatic.cpp中定义为静态全局变量,因此无法在main.cpp中使用,运行会提示 “无法解析的外部符号”

//main.cpp
#include <iostream>
#include "static.h"
using namespace std;

int a = 5; //全局变量

int main()
{
	extern int max; //申明静态全局变量,运行失败,想用max,则max需定义为全局变量,而不是静态全局变量
	
	cout << "max: " << max << endl;

	fun();

	return 0;
}
//static.pp
#include <iostream>
#include  "static.h"
using namespace std;

static int max = 1000000; //静态全局变量,要想在main.cpp中使用,需定义为全局变量
//int max = 1000000; 
 void fun(void)
 {
	 int min = 11;
	 cout << "min:" << min << endl;

 }
//static.h
#include <iostream>

void fun(void);

运行结果: 无法编译成功
在这里插入图片描述
想使用static.cpp中的全局变量max,则需要定义为全局变量,而不是静态全局变量。
在这里插入图片描述

静态局部变量

局部变量:
在程序中只在特定过程和函数中可以访问的变量,是相对于全局变量而言的。在C等面向过程语言中,局部变量可以和全局变量重名,但是局部变量会覆盖全局变量。在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。
静态局部变量:
定义在函数体内的变量加上static修饰符,它的存在意义是随着第一次函数的调用而初始化,但却不随着函数的调用结束而销毁。因此静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。

举例:

#include <iostream>
using namespace std;
void test(void)
{
	int a = 10; // 局部变量
	static int b = 10; //静态局部变量

	a++;
	b++;
	cout << "a:" << a << ", b: " << b << endl;
}
int main()
{
	test();
	test();
	test();
	test();
	test();
	test();

	return 0;
}

运行结果,可以看到局部变量和静态局部变量的差异。
在这里插入图片描述

静态函数

函数:
c/c++函数是c/c++程序的基本组成单位,用于实现特定的功能或计算。

静态函数:
在函数定义前加上修饰符static,作用和静态全局变量类似;函数的定义和生命在默认状态下都是extern的,但静态函数只是在申明他的文件当中可见,不能被其余文件所用。
举例:

//main.cpp
#include <iostream>
#include "static.h"

using namespace std;


int main()
{
	fun();
	test();//报错,无法调用static.cpp中的静态函数

	return 0;
}
//static.cpp
#include <iostream>
#include  "static.h"
using namespace std;

//普通函数
 void fun(void)
 {
	 int min = 11;

	 cout << "min:" << min << endl;

 }

 //静态函数,无法在其他文件中使用该函数
 static void test(void)
 {
	 int min = 1111;
	 cout << "min:" << min << endl;

 }
//static.h
#include <iostream>

void fun(void);

static void test(void);

运行结果:可以看到,在main函数中调用test()函数,会提示声明未定义。
在这里插入图片描述

类的静态成员和静态成员函数

类的静态成员:
修饰class的数据成员,这种数据成员的生存期大于class的对象;静态数据成员是每个class有一份,普通数据成员是每个实例有一份,因此静态数据成员也叫类变量,普通数据成员也叫实例变量。

类的静态成员函数:
在成员函数前加上static就变成了静态成员函数;静态成员函数不能访问非静态成员函数或数据成员,但非静态可以访问静态。
因为静态是属于类的,无法感知创建的对象,所以它对你对象的函数或者数据是一无所知的,所以它没办法调用;而反过来,创建的对象是对类是可以感知的,所以是可以调用类函数和类成员的。
静态成员函数能够继承和覆盖,但没法是虚函数。

#include <iostream>
using namespace std;

class A
{
public:
	static int a; //类的静态成员变量
	static int get_a();//类的静态成员函数

	int b;
	int get_b();
};
int A::a = 100; //静态成员变量可以在类的外部直接定义
//int A::b = 1000; //普通成员变量在类的外部定义失败

int A::get_a()
{
	return a; //类的静态成员函数只能访问类的静态成员变量
	//return b + a; //静态成员函数无法调用普通成员变量
}
int A::get_b()
{
	return b + a;//普通成员函数可以调用静态成员变量
}

int  main(void)
{
	cout << "a: " << A::get_a() << endl; //不需要类的实例,也可以调用来的都静态成员函数

	A m;
	m.b = 90;
	m.a = 100000;

	cout << m.get_a() << endl;
	cout << m.get_b() << endl;
	cout << m.a << endl;

	return 0;

}

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/319714.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

优雅的删除链表元

王有志&#xff0c;一个分享硬核Java技术的互金摸鱼侠加入Java人的提桶跑路群&#xff1a;共同富裕的Java人 在数据结构&#xff1a;链表中&#xff0c;我们实现了链表的删除方法&#xff0c;但代码看起来并不“优雅”&#xff0c;那么今天我们就来尝试使用多种方法&#xff0c…

【深度学习:Micro-Models】用于标记图像和视频的微模型简介

【深度学习&#xff1a;Micro-Models】用于标记图像和视频的微模型简介 微模型&#xff1a;起源故事微模型到底是什么&#xff1f;更详细地解释微观模型&#xff1a;一维标签蝙蝠侠效率 在计算机视觉项目中使用微模型的额外好处面向数据的编程 在本文中&#xff0c;我们将介绍 …

SystemC学习笔记 - Hello systemc world

Hello Systemc World 码农老规矩&#xff0c;先写一个hello world并输出&#xff0c;语法什么的后面再说&#xff0c;先能编译运行再说。 目录配置 使用examples里的配置&#xff0c;在examples/sysc目录下创建test目录&#xff0c;其下创建第一个test1的目录&#xff0c;如…

【Py/Java/C++三种语言详解】LeetCode每日一题240114【链表】LeetCode83、删除排序链表中的重复节点

文章目录 题目链接题目描述解题思路代码PythonJavaC时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目链接 LeetCode83、删除排序链表中的重复节点 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返…

寡年是否适合结婚?寡妇年结婚有什么禁忌吗?让程序来告诉你有多少人是寡妇年结婚的。

什么是寡年&#xff1f; 百度百科 原文&#xff1a;寡年-百度百科 指整年没有“立春”的日子就是“盲年”&#xff0c;俗称寡年。又名滑头年 社会上流传的“寡妇年”&#xff0c;是指整个农历年都没有立春的年份。以农历2005年的鸡年为例&#xff0c;立春在公历2月4日&…

8年老鸟,自动化测试经验,测试数据管理分析总结,一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 问题&#xff1a;…

Linux 转换文字编码与换行符 nkf命令

参考资料 【 nkf 】コマンド――文字コードと改行コードを変換するnkfコマンドでファイルの文字コードと改行コードを統一する 目录 一. 前期准备二. 乱码现象与分析三. nkf命令3.1 nkf --guess 查看文件编码3.2 nkf -w8 UTF-8(BOM)编码显示3.3 nkf -wd --overwrite 覆盖源文件…

关于CodeReview的一些实践和思考

在日常开发中&#xff0c;Code Review 的重要性日益凸显。它不仅有助于提升代码质量&#xff0c;还促进了团队成员之间的知识共享和技能提升。本文将主要聚焦于 Code Review&#xff0c;分享在这个过程中的一些心得和思考。 CodeReview常用到的一些术语 之前看到公司的大佬经…

项目进度管理

7过程 计划过程组6项&#xff1a;规划进度管理&#xff0c;定义活动&#xff0c;排列活动顺序&#xff0c;估算活动资源&#xff0c;估算活动持续时间&#xff0c;制定进度计划&#xff0c; 监控过程组1项&#xff1a;控制进度 1、规划进度管理&#xff0c; 对项目过程中管理…

Webpack模块打包工具

目录 Webpack模块打包工具知识点自测01.Webpack 简介以及体验目标讲解小结 02.Webpack 修改入口和出口目标讲解小结 03.案例-用户登录-长度判断目标讲解小结 04.Webpack 自动生成 html 文件目标讲解小结 05.Webpack-打包 css 代码目标讲解小结 06.优化-提取 css 代码目标讲解小…

C++学习笔记——继承和动态内存分配

目录 一、继承 二、动态内存分配 三、继承的细节 四、动态内存分配细节 五、一个动物园管理系统 继承和动态内存分配是C中两个重要的概念 一、继承 继承是C中面向对象编程的一个重要特性&#xff0c;它允许我们创建一个新类&#xff0c;该类从现有的类中继承属性和方法&…

设置ubuntu命令行样式

目录 一、脚本 二、含义 三、颜色设置 四、展示 五、注意 上次为了学习ros安装了一个22.04并且做了简单的配置&#xff0c;这次我们进一步对命令行样式进行配置 ubuntu22.04安装与配置_ubuntu22.04硬件配置-CSDN博客 一、脚本 这是他的默认配置&#xff0c;太长了&#x…

Python--循环语句

在 Python 中&#xff0c;循环语句用于重复执行一段代码多次。Python 主要提供了两种类型的循环&#xff1a;for 循环和 while 循环。 1. for 循环 for 循环用于遍历可迭代对象&#xff08;如列表、元组、字典、字符串等&#xff09;中的每个元素&#xff0c;并对每个元素执行…

【每日一题】构造限制重复的字符串

文章目录 Tag题目来源解题思路方法一&#xff1a;贪心空间复杂度&#xff1a; O ( ∑ ) O(\sum) O(∑)。 写在最后 Tag 【贪心】【字符串】【2024-01-13】 题目来源 2182. 构造限制重复的字符串 解题思路 方法一&#xff1a;贪心 思路 解题思想比较简单&#xff0c;利用贪…

C++进阶--红黑树

红黑树 一、红黑树的概念二、红黑树的性质三、红黑树结点的定义四、红黑树的插入五、红黑树的验证七、红黑树的查找七、红黑树与AVL树的比较七、完整代码RBTree.h 一、红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色…

IaC基础设施即代码:使用Terraform 连接 alicloud阿里云

目录 一、实验 1.环境 2.alicloud阿里云创建用户 3.Linux使用Terraform 连接 alicloud 4.Windows使用Terraform 连接 alicloud 二、问题 1.Windows如何申明RAM 相关变量 2.Linux如何申明RAM 相关变量 3. Linux terraform 初始化失败 4.Linux terraform 计划与预览失败…

关于高通Android 平台上qssi的介绍

1. QSSI 是 Qualcomm Single System Image 的缩写。 2. Android Q上开始支持QSSI。 3. QSSI 是用来编译system.img的 3.1 QSSI编译注意事项 lunch qssi ------ 编译system.img lunch target ------ 编译其余的image 3.2 有QSSI和没有QSSI的编译流程对比 没有QS…

YOLOv5独家原创改进:多层次特征融合(SDI)结合PConv、DualConv、GSConv,实现二次创新 | UNet v2最新论文

💡💡💡本文独家改进:多层次特征融合(SDI)高效结合DualConv、PConv、GSConv等实现二次创新 1)替代原始的Concat; 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_12511931.html 💡💡💡全网独家首发创新(原创),适合paper !!! 💡�…

Docker运行RabbitMQ并使用SpringAMQP操作

文章目录 一、RabbitMQ运行二、整合SpringAMQP1. 引入依赖 三、测试1. 消费者2. 生产者3. 运行 一、RabbitMQ运行 拉取docker镜像 docker pull rabbitmq:3-management基础运行命令 docker run \-e RABBITMQ_DEFAULT_USERrabbitmq \-e RABBITMQ_DEFAULT_PASSrabbitmq \--name…

Vue3 如何使用移动端调试工具vConsole

1、安装 pnpm i vconsole2、在src/utils下新建vconsole.ts&#xff0c;写入以下代码 // 这是移动端控制台调试工具&#xff0c;需要调试就打开,不用就注释 import vConsole from vconsole const vconsole new vConsole()3、src/main.ts 引入&#xff0c;需要调试就打开,&…