深入解析C和C++中的static关键字

C和C++中的"static"关键字是一个非常强大且多用途的特性,它在内存分配、变量生命周期、函数行为等方面有着多种用途。在这篇博客中,我们将详细探讨"static"关键字在C和C++中的使用方法和性能影响,并提供一些实际示例来帮助读者更深入理解。

一、静态变量(Static Variables):

  • 局部静态变量: 在函数内部定义的静态变量具有静态存储期和块作用域,仅在首次调用时进行初始化,保持其值在函数调用之间的持久性。
  • 全局静态变量: 在函数外部定义的静态变量具有静态存储期和文件作用域,仅在当前源文件中可见,可以被多个函数共享。

C语言中的静态变量

在C语言中,"static"关键字主要用于定义静态变量。静态变量的特点是它们的空间只在程序执行期间分配一次,并且只在程序结束时释放。这意味着无论函数调用多少次,静态变量的值都保持不变。

#include <stdio.h>
int fun() {static int i = 0;  // 静态变量i++;return i;
}
int main() {printf("%d %d %d\n", fun(), fun(), fun());return 0;
}

上述代码中,每次调用fun函数时,i的值都会保留上次的值,而不是重新初始化为0。这是因为i是一个静态变量,它的值在程序执行期间保持不变。

C++中的静态成员

在C++中,"static"关键字不仅可以用于定义静态变量,还可以用于定义类的静态成员。静态成员不属于类的任何对象,而是属于整个类。这意味着所有对象共享同一个静态成员。

#include <iostream>
class MyClass {
public:static int staticMember;  // 静态成员void nonStaticMember() {staticMember++;}
};
int MyClass::staticMember = 0;  // 静态成员的初始化
int main() {MyClass obj1;MyClass obj2;obj1.nonStaticMember();obj2.nonStaticMember();std::cout << "Static member value: " << MyClass::staticMember << std::endl;return 0;
}

上述代码中,staticMember是一个静态成员变量,它被所有MyClass对象共享。当我们通过两个不同的对象调用nonStaticMember函数时,它们实际上是在修改同一个静态成员变量的值。

二、静态函数(Static Functions):

  1. 静态函数在C和C++中具有内部链接(internal linkage),只能在定义它的源文件内部访问。
  2. 静态函数不会与其他源文件中的同名函数发生冲突,可以避免命名空间污染问题。

在C++中,"static"关键字还可以用于定义静态函数。静态函数只能通过类名调用,不能通过对象调用。

#include <iostream>
class MyClass {
public:static void staticFunction() {std::cout << "Static function called." << std::endl;}
};
int main() {MyClass::staticFunction();return 0;
}

上述代码中,staticFunction是一个静态函数,它可以通过类名MyClass::来调用,而不是通过对象调用。

三、静态类成员(Static Class Members):

在C++中,类的静态成员变量 属于整个类而不属于特定的对象,具有以下特点:

  • 所有类的对象共享同一份静态成员变量,只有一个副本存在于内存中。
  • 可以通过类名加作用域解析运算符(::)直接访问,无需创建对象的实例。
class MyClass {
public:static int staticVar; // 声明静态成员变量
};int MyClass::staticVar = 5; // 初始化静态成员变量int main() {cout << MyClass::staticVar << endl; // 输出 5MyClass::staticVar = 10; // 直接修改静态成员变量的值return 0;
}

静态成员函数 属于类而不属于类的任何特定对象,具有以下特点:

  • 可以直接访问静态成员变量,无需创建对象的实例。
  • 不具有this指针,无法访问非静态成员变量和非静态成员函数。
class MyClass {
public:static void staticFunction() {cout << "This is a static function" << endl;}
};int main() {MyClass::staticFunction(); // 可以直接调用静态成员函数return 0;
}

四、static与作用域的关系:

  1. 在函数内部声明的静态变量具有块作用域,只能在函数内部访问。
  2. 静态函数具有文件作用域,只能在定义它的源文件内部访问。
  3. 静态类成员变量和函数属于类作用域,在类的任何对象之间共享。

五、static的使用场景和优势:

  1. 数据共享:静态变量和静态类成员可以在多个函数或对象之间共享数据。
  2. 命名空间隔离:静态函数和静态类成员可以避免与其他源文件中同名函数或成员发生冲突。
  3. 提高效率:静态变量和静态函数的生命周期较长,可以减少内存的频繁分配和释放操作。

六、性能影响

使用"static"关键字可能会对程序的性能产生一定影响。静态变量和成员在程序执行期间只分配一次内存,这意味着它们的空间是固定的,不能被动态分配和释放。在某些情况下,这可能会导致内存浪费或者程序运行效率降低。

然而,在许多情况下,使用"static"关键字可以提高程序的性能。例如,当我们需要保留一些状态信息或者在多个函数之间共享一些数据时,使用静态变量可以避免在每次函数调用时都进行内存分配和释放,从而减少内存操作的开销。

对于静态成员和函数,它们的所有对象共享同一个内存空间,这可以减少内存使用量,提高程序的运行效率。

七、实际示例

下面是一个实际的示例,展示了"static"关键字在C和C++中的使用。

#include <stdio.h>
class MyClass {
public:static int staticMember;void nonStaticMember() {staticMember++;}
};
int MyClass::staticMember = 0;
int fun() {static int i = 0;i++;return i;
}
int main() {MyClass obj1;MyClass obj2;obj1.nonStaticMember();obj2.nonStaticMember();printf("Static member value: %d\n", MyClass::staticMember);printf("fun() return value: %d\n", fun());printf("fun() return value: %d\n", fun());return 0;
}

八、总结

通过本文的详细介绍,我们对C和C++中的static关键字有了深入的理解。它在不同的上下文中具有不同的用法和作用,包括修饰变量、函数和类成员。合理地使用static关键字可以提高程序的效率、隔离命名空间以及实现数据的共享和持久性。在日常编程中,我们应根据具体需求灵活运用static关键字,充分发挥其优势,写出更加高效、可靠的代码。

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

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

相关文章

RuntimeError: CUDA out of memory.【多种场景下的解决方案】

RuntimeError: CUDA out of memory.【多种场景下的解决方案】 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;【Matplotlib之旅&#xff1a;零基础精通数据可视化】 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于深度学…

SQL Developer 小贴士:显示Trace文件

SQL Developer可以识别trace文件&#xff0c;而无需利用tkprof进行转换。 在数据库服务器上生产trace文件。例如&#xff1a; alter session set tracefile_identifierdemo01_02;alter session set sql_tracetrue;-- your SQL here, for example select * from hr.employees;a…

防御第六次作业-防火墙综合实验(av、url过滤、dns过滤)

目录 拓扑图&#xff1a; 要求&#xff1a; 8 9 10 11 拓扑图 要求 前7个要求在上一篇博客&#xff1b; 8.分公司内部的客户端可以通过域名访问到内部的服务器 9.假设内网用户需要通过外网的web服务器和pop3邮件服务器下载文件和邮件&#xff0c;内网的FTP服务器也需要…

【Redis高手修炼之路】④主从复制

主从复制 就是 redis集群的策略配从&#xff08;库&#xff09;不配主&#xff08;库&#xff09;&#xff1a;小弟可以选择谁是大哥&#xff0c;但大哥没有权利去选择小弟读写分离&#xff1a;主机写&#xff0c;从机读 一主二仆 准备三台服务器&#xff0c;并修改redis.co…

【复现】Wuzhi cms后台sql注入漏洞_53

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一: 四.修复建议:

Linux系统调用、程序执行相关命令(待补充)

在Linux系统中&#xff0c;有多种工具可以用于跟踪系统调用、程序执行、性能分析等。这里列出一些常用的跟踪工具&#xff1a; strace: 用于跟踪进程执行时的系统调用和接收到的信号。它对于理解程序如何与Linux内核交互非常有用。 使用示例&#xff1a; strace lsltrace: 类似…

Linux归档命令cpio

cpio 是一种在 Unix 和类 Unix 系统&#xff08;如 Linux&#xff09;上用于创建和提取归档文件的工具。与 tar 命令类似&#xff0c;cpio 可以用来打包和解包文件和目录&#xff0c;但它在某些方面提供了不同的功能和选项。cpio 命令通常与 find 命令结合使用&#xff0c;以创…

Spin Image特征描述子简介

一、向量点积 二、狄拉克δ函数公式 三、Spin Image特征描述子原理 Spin Image自旋图像描述符可视化以及ICP配准-CSDN博客

C++结合Lambda表达式在函数内部实现递归

529. 扫雷游戏 已解答 中等 相关标签 相关企业 让我们一起来玩扫雷游戏&#xff01; 给你一个大小为 m x n 二维字符矩阵 board &#xff0c;表示扫雷游戏的盘面&#xff0c;其中&#xff1a; M 代表一个 未挖出的 地雷&#xff0c;E 代表一个 未挖出的 空方块&#xff…

【XR806开发板试用】+移植rosserial到XR806

1 XR806简介 板子来源于极术社区的试用&#xff0c;XR806的在线网址 其主要参数&#xff1a; 主控XR806AF2LDDRSIP 288KB SRAM存储SIP 160KB Code ROM. SIP 16Mbit Flash.天线板载WiFi/BT双天线&#xff0c;可共存按键reboot按键 1&#xff0c;功能按键 1灯红色电源指示灯 1…

如何使用阿里云OSS进行前端直传

在使用阿里云OSS进行前端直传时&#xff0c;首先我们需要去阿里云官网注册自己的存储桶&#xff0c;然后申请相关的accessKeyId和accessKeySecret&#xff0c;然后新建一个桶&#xff0c;为这个桶命名以及选择对应的地区。 然后可以根据自己的业务&#xff0c;封装对应的组件&a…

安卓11-HDMI插拔检测流程

hdmi从插入到拔出经过底层一系列检测到应用层&#xff0c;应用层获取hdmi插入状态后又会做出一系列相应的动作&#xff0c;下面梳理了从应用层到底层一步步追踪到芯片的hpd-pin的检测过程。 frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.…

测试开发【Mock平台】14基础:拦截器服务实现(五) 规则查询代码

【Mock平台】为系列测试开发教程&#xff0c;从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台&#xff0c;希望作为一个实战项目对各位的测试开发学习之路有帮助&#xff0c;关注公众号发送“mock”获取github项目源码地址&#xff0c;大奇一个…

ctfshow-web29~40-WP

web29 if(isset($_GET[c])){$c = $_GET[c];if(!preg_match("/flag/i", $c)){eval($c);}}else{highlight_file(__FILE__); } 首先先system(“ls”);查看一下文件 既然过滤了flag,那我们就fla*的形式进行匹配,结合tac命令输出flag.php文件内容

@ 代码随想录算法训练营第8周(C语言)|Day55(动态规划)

代码随想录算法训练营第8周&#xff08;C语言&#xff09;|Day55&#xff08;动态规划&#xff09; Day55、动态规划&#xff08;包含题目 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费 &#xff09; 309.最佳买卖股票时机含冷冻期 题目描述 给定一个整…

探秘GNU/Linux Shell:命令行的魔法世界

GNU/Linux的Shell是一种特殊的交互式工具&#xff0c;为用户提供了强大的控制和管理Linux系统的方式。在这个博客中&#xff0c;我们将深入了解Shell的基本概念、功能以及不同类型的Shell。 Shell的本质 Shell的核心是命令行提示符&#xff0c;它是用户与Linux系统进行交互的…

拿捏c语言指针(下)

前言 此篇讲解的主要是函数与指针的那些事~ 书接上回 拿捏c语言指针&#xff08;上&#xff09;和 拿捏c语言指针&#xff08;中&#xff09; ​​​​​​没有看的小伙伴要抓紧喽~ 欢迎关注​​个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#x…

有哪些好用的网页原型网站?

与桌面端相比&#xff0c;在线网页原型网站的使用具有优势&#xff0c;因为在线网页原型网站在整个使用过程中不需要安装&#xff0c;在线网页原型网站在任何地方都没有限制。更重要的是&#xff0c;无论是现在使用的Linux&#xff0c;在线网页原型网站在操作系统中都没有限制、…

kafka集群部署(kraft)

下载地址 https://archive.apache.org/dist/kafka 上传并解压 tar -zxvf kafka_2.13-3.6.1.tgz建立软连接 ln -s /usr/local/kafka_2.13-3.6.1 kafka创建数据目录 mkdir -p /home/data/kafka修改配置 多台服务器都要修改 vi /usr/local/kafka/config/kraft/server.propert…

一.重新回炉Spring Framework: 理解Spring IoC

1. 写在前面的话 说实话&#xff0c;从事java开发工作时间也不短了&#xff0c;对于Spring Framework&#xff0c;也是天天用&#xff0c;这期间也碰到了很多问题&#xff0c;也解决了很多问题。可是&#xff0c;总感觉对Spring Framework还是一知半解&#xff0c;不能有个更加…