C/C++易错知识点(4):static修饰变量和函数

news2024/11/20 16:36:30

static是C/C++中一个非常容易混淆的语法,在不同的地方针对不同的对象有不同的效果。

它在大型项目中有至关重要的作用,需要我们详细研究。

1.变量

所有static修饰的变量的生命周期都是自调用它起到程序结束,期间这些变量都只会初始化一次

①全局定义的变量

全局变量具有外部链接属性,也就是说其它文件可以对它使用extern进行访问。

注意全局变量不要在.h中定义,因为如果有两个或以上的.c文件包含了这个.h,那么在预处理后这个变量就会分别展开到两个文件中,在链接阶段就会查出重定义。

正确的做法应该是在.h中声明extern int a,这样就相当于告诉包含该.h的文件外部有一个全局变量a可以使用。在链接的时候就会到所有的文件中去找这个a。注意这和局部变量使用并不冲突。

②static修饰全局变量

在static修饰全局变量之后,就意味着这个全局变量只能在该文件以及包含它的文件使用了,而无法通过extern来访问

③在类中使用static变量

在类中static变量隶属于对应的类,而并不会被实例化,也就是说创建对象的时候我们没有为这个static变量开辟空间(自然也不能给它缺省值和初始化)。

类的static变量初始化一般是在外部进行,且能够直接通过类来直接访问。我们完全可以将static变量理解成这个类的公共区域,只有一份(和函数相似),所有对象都不包含它

至于如果static变量为私有的情况,后面会讲到。

2.函数

①全局定义和声明时

在我们全局定义函数的时候,函数是带有外部链接属性的(外部文件可以访问它)。我们可以在一个.c定义函数,然后在.h中声明这个函数,如果有很多.c都包含了这个.h,那就相当于告诉它们在程序中存在这个函数的定义,在链接的时候会去所有文件找这个函数(就算这个文件没有包含相应的.h)。

总结:声明只是告诉编译器有这么一个函数,在编译的语法检查中不会报错,但是这个函数是否存在需要到链接的阶段才能检查出来。当全局定义函数时,会到所有的文件中去找函数(这里先假设所有的函数都没有被static修饰),找到了就调用,找不到就报链接错误。声明处得不到函数的地址,定义处才能得到。

②定义处使用static

使用static修饰这个函数的时候,函数就变成了静态函数,具有内部链接属性,也就是只在当前文件及包含它的文件可以访问,而其它外部文件不能对它进行访问。

声明处使用static

这里非常容易混淆。在.h声明Fun()函数的地方使用static,如果有n个.c都包含了这个.h,那就告诉我们有n个完全独立的Fun()存在。很多人这里应该很难理解,下面我会画图分情况来解释:

但是这里要注意一个易错点,我们不能完全认为static函数的作用域是.i的内部。因为当在.h中声明了static函数,在.c中包含该.h并定义了static函数的情况下,我们没有办法直接在.h中调用该函数。上面图中所说的“static函数只能在当前.i中访问”并不意味着.i的任意位置都能调用。

换句话说,static函数只能在预处理前(原始文件)的定义的当前文件以及包含它的文件可以调用。

注意区分“包含它的文件”和“它包含的文件”,上面我举例的.h中无法调用static函数就是“它包含的文件”这种情况。

④类中定义或声明

在类中定义的static函数和static变量类似,它相当于类的公共区域,这个函数的特殊之处在于它的第一个参数没有this指针,这也就意味着static函数能够访问static变量。因为非static成员函数都会有一个隐含的this指针,在类里访问成员是实质上都是this->_a,但如果这里的_a是static变量的话,就矛盾了,因为static变量不存在于对象中,自然this访问不到它。

所以只有static函数在调用_a时不会变成this->_a,可以得到static成员变量的值。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

yolov8实战第七天——pyqt5-yolov8实现车牌识别系统(参考论文(约7000字)+环境配置+完整部署代码+代码使用说明+训练好的模型)

基于 pyqt5-yolov8实现车牌识别系统,包括图片车牌识别,视频车牌识别,视频流车牌识别。 效果展示(图片检测,检测到的内容添加到历史记录): 效果展示(视频检测,视频车辆只会添加一条记录,下文更多实际应用中的优化策略): 基于YOLOv8和PyQt5的车牌识别系统设计与…

Linux 操作系统非缓冲区的文件操作、时间编程

1、文件操作 1.1 基于缓冲区的文件操作 基于缓冲区的文件操作---高级Io 以f开头的是基于缓冲区的文件操作 printf是一个基于缓冲区的函数 输出条件: 1.程序正常运行 2.遇到换行\n也能输出 3.缓存区内存已满 1024大小 4.遇到fflush(stdout&a…

【每日刷题】Day19

【每日刷题】Day19 🥕个人主义:开敲🍉 🔥所属专栏:每日刷题🍍 目录 1. 55. 跳跃游戏 - 力扣(LeetCode) 2. 62. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径…

48-PCIE转串口和并口电路设计

视频链接 PCIE转串口和并口电路设计01_哔哩哔哩_bilibili PCIe转串口和并口电路设计 1、PCIe转串并口电路设计基本介绍 2、PCIe转串口和并口的方案(京东) 2.1、PCIe转串口 2.1.1、ASIX (亚信)MCS9922-PCIe转2路RS232扩展卡 2.1.2、ASIX (亚信)MCS9900-PCIe转4路RS232扩展卡…

【ARM 裸机】I.MX 启动方式之启动头文件 2

接上一节:【ARM 裸机】I.MX 启动方式之启动头文件 1; 2.3、DCD DCD,Device Configuration Data ,就是配置 6ULL 寄存器的,DCD 数据最大限制 1768 字节; CCGR0 是不是很熟悉?对,在…

C++实战——日期类的实现

日期类的实现 前言一、日期类概念实现运用场景 二、日期类的具体实现代码构造函数拷贝构造函数获取日期(内联函数)赋值加等减等加减小于小于等于大于大于等于相等不相等前置后置前置- -后置- -关于类里重载的比较运算符为什么要加外部const示例 Date.hDa…

鸢尾花数据集的KNN探索与乳腺癌决策树洞察

鸢尾花数据集的KNN探索与乳腺癌决策树洞察 今天博主做了这个KNN和决策树的实验。 一.数据集介绍 介绍一下数据集: 威斯康星州乳腺癌数据集: 威斯康星州乳腺癌数据集(Wisconsin Breast Cancer Dataset)是一个经典的机器学习数…

git 快问快答

我在实习的时候,是用本地开发,然后 push 到 GitHub 上,之后再从 Linux 服务器上拉 GitHub 代码,然后就可以了。一般程序是在 Linux 服务器上执行的,我当时使用过用 Linux 提供的命令来进行简单的性能排查。 在面试的时…

YMP实现Oracle迁移到YashanDB

迁移需求 ip地址 数据库信息 操作系统信息 源库 192.168.3.132 实例名topdh 用户密码TOPICIS/oracle 端口1521 Centos7.9 x86_64 目标库 192.168.3.175 实例名yasdb 用户密码topicist/opicis 端口1688 Centos7.9 x86_64 迁移前准备 YMP工具获取 根据实际需求向厂…

晨昏线学习

看视图记得标自转方向

C语言指针进阶:数组与指针的联系

目录 1. 数组名的本质2. 使用指针访问数组3. 一维数组传参的本质4. 二级指针5. 指针数组5.1 指针数组模拟二维数组 正文开始。 1. 数组名的本质 数组名代表着这个数组中第一个元素的地址 例如: int arr[4] { 1,2,3,4 }; int *p1 &arr[0]; int *p2 arr;上述…

MATLAB R2024a:重塑商业数学软件的未来

在数字化浪潮席卷全球的今天,商业数学软件已经成为企业、研究机构乃至个人不可或缺的工具。而在这其中,MATLAB R2024a以其卓越的性能和广泛的应用领域,正逐步成为商业数学软件的新标杆。 MATLAB R2024a不仅继承了前代版本的优秀基因&#xf…

VirtualBox Manjaro Linux(kde)虚拟机扩容 增大硬盘存储空间

https://blog.csdn.net/m0_65274357/article/details/131965463 df -h发现/可用空间之后几百M了 文件系统 大小 已用 可用 已用% 挂载点 dev 2.0G 0 2.0G 0% /dev run 2.0G 1.2M 2.0G 1% /run /dev/sda1 40G 37…

手把手教你实现 C 语言的函数多参默认值 「上」

以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/nj0C9SbAuzUOPt_J1n8B_Q 自从上一篇关于 C 语言单个参数函数的默认值实现《C语言函数也可以给形参添加默认值?》发表以来,…

构建Python中的分布式日志系统:ELK与Fluentd的结合

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在现代软件开发中,日志系统是至关重要的组成部分。它们不仅用于故障排查和性能监…

跟TED演讲学英文:How AI could empower any business by Andrew Ng

How AI could empower any business Link: https://www.ted.com/talks/andrew_ng_how_ai_could_empower_any_business Speaker: Andrew Ng Date: April 2022 文章目录 How AI could empower any businessIntroductionVocabularyTranscriptSummary后记 Introduction Expensiv…

MySQL与Redis缓存一致性的实现与挑战

缓存是提高应用性能的重要手段之一,而 MySQL 和 Redis 是两种常用的数据存储和缓存技术。在许多应用中,常常将 Redis 用作缓存层,以加速对数据的访问。然而,在使用 MySQL 和 Redis 组合时,保持缓存与数据库之间的一致性…

使用 Flask 和 Flask-Login 构建用户认证的 Web 应用程序

在本篇技术博客中,我们将学习如何使用 Flask 框架和 Flask-Login 扩展构建一个具有用户认证功能的简单 Web 应用程序。我们将从创建 Flask 应用实例开始,然后逐步添加用户认证功能。 1. 安装依赖库 首先,确保您已经安装了 Flask、Flask-PyM…

【题解】NC398 腐烂的苹果(多源BFS)

https://www.nowcoder.com/practice/54ab9865ce7a45968b126d6968a77f34?tpId196&tqId40529&ru/exam/oj 从每个腐烂的苹果开始使用广度优先遍历&#xff08;bfs&#xff09; class Solution {int n, m;int dx[4] {0, 0, 1, -1};int dy[4] {1, -1, 0, 0};vector<v…

[AI OpenAI-doc] 微调

学习如何为您的应用程序定制模型。 介绍 微调允许您通过提供以下内容&#xff0c;从 API 提供的模型中获得更多收益&#xff1a; 比提示更高质量的结果能够训练比提示中能容纳的更多示例由于提示更短而节省的标记更低的延迟请求 OpenAI 的文本生成模型已经在大量文本上进行…