C++之extern和static用法和区别

2023-11-08

声明和定义的区别

  • 变量定义:用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。
  • 变量声明:用于向程序表明变量的类型和名字,不给变量分配存储空间。

例1:

int a = 0;  //定义并声明变量a
extern int a ;  //只是声明变量a

关键字extern

通过使用extern关键字声明变量名而不定义它。
extern表明变量或者函数是定义在其他其他文件中的,并且用关键字extern声明的变量的作用域是整个工程。

作用:

显式的说明某变量a的存储空间是在程序的其他地方分配的,在文件中其他位置或者其他文件中寻找a这个变量。

用法总结:
  • 对变量进行声明;(说明在别的文件中已经定义了该变量,当前进行声明是要引用别的文件中定义的该变量)
    注意:对变量进行声明时,变量定义时必须是全局变量,否则运行会出现错误。

例2:
main.cpp

#include <iostream>
using namespace std;
int main()
{
	extern int a;
	extern int b;
	int c = a + b;
	cout << "c:" << c << endl;
	
	return 0;

}

practice.cpp

#include <iostream>
using namespace std;

int a = 1;
int b = 2;

main.cpp的运行结果:

C:3

分析:变量a和变量b在practice.cpp文件中定义了;在main.cpp文件中进行声明,所以程序会在整个工程中进行搜索,并进行计算。

  • 对函数进行声明

例3:
main.cpp

#include <iostream>
using namespace std;
int a = 1;
int b = 2;
int main()
{
	extern void fun();
	fun();
	return 0;
}

practice.cpp

#include <iostream>
using namespace std;
extern int a;
extern int b ;
void fun(void)
{
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
}

运行结果:

a:1
b:2

分析:函数fun()在practice.cpp文件中定义了;在main.cpp文件中进行声明,会调用practice.cpp中定义的函数。

  • extern和include的区别
    include相当于把include .h文件直接带入到本源文件里,比如在b.c文件里include “a.h”,就相当于把a.h文件里所有定义的变量和函数全部拷贝了一份放入了b.c里,一个项目里,一个.h文件可能会被多个.c源文件包含,这样编译的时候就会报重复定义的错误。而且尽量不要在.h里定义变量,这是一个不好的习惯。
  • extern "C"的作用
    extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。

关键字static

static可以用来修饰全局变量,局部变量以及函数

  • 修饰全局变量时,表明一个全局变量只对定义在同一文件中的函数可见。
  • 修饰局部变量时,表明该变量的值不会因为函数终止而丢失。
  • 修饰函数时,表明该函数只在同一文件中调用。

全局变量和全局静态变量区别

  • 全局变量:作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern 全局变量名的声明,就可以访问全局变量。
  • 全局静态变量:(是static修饰的全局变量)作用域是所在的文件,其他的文件即使用extern声明也不能访问。

也就是加上static修饰的全局变量,限制了变量的使用范围;未经初始化的全局静态变量会被自动初始化为0。

局部静态变量

  • 作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,并没有销毁,而是仍然驻留在内存当中,只不过我们不能再对它进行访问,直到该函数再次被调用,并且值不变;

例1:定义局部变量

#include <iostream>
using namespace std;
int main()
{
	for (int i = 0; i < 5; i++)
	{
	   int a = 1;
	   a = a + 1;
	   cout << "a:" << a << endl;
	}
	return 0;
}

运行结果:

a:2
a:2
a:2
a:2
a:2

例2:定义局部静态变量

#include <iostream>
using namespace std;
int main()
{
	for (int i = 0; i < 5; i++)
	{
	   static int a = 1;
	   a = a + 1;
	   cout << "a:" << a << endl;
	}
	return 0;
}

运行结果:

a:2
a:3
a:4
a:5
a:6

说明:局部静态变量每次迭代计算,上一次的值都保留在内存中;

静态函数

在函数返回类型前加关键字static,函数就定义成静态函数。函数的定义和生命在默认情况下都是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++之extern和static用法和区别 的相关文章

随机推荐

  • selenium数据提取学习(1)

    import time from selenium import webdriver 设置浏览器 driver webdriver Edge 控制浏览器访问地址 driver get https www baidu com time sle
  • 【DTale】数据分析强大工具DTale的使用

    简单介绍 使用dtale 启动 数据加载 功能介绍 主菜单选项 0 切换语言 1 创建列 2 汇总数据 3 缺失率分析 4 绘图 5 高亮功能 6 代码导出 数据导出 列菜单功能 1 冻结 2 隐藏和删除 3 替换和类型转换 4 描述性统计
  • tomcat的多实例和动静分离

    多实例 在一台服务器上有多个tomcat服务 配置成全局变量 方便后面传参 安装tomcat 安装好 jdk后编译安装tomcat cd opt tar zxvf apache tomcat 9 0 16 tar gz mkdir usr
  • android蓝牙键盘光标,罗技K810背光蓝牙键盘快捷键大全

    最近入手了一款罗技K810背光蓝牙键盘 该怎么使用键盘的快捷键实现快捷操作呢 下面我们就来看看罗技K810背光蓝牙键盘快捷键大全 需要的朋友可以参考下 一 PC版键盘上的WIN键相当于MAC iOS系统的command键 文本输入状态下 S
  • WiFi6技术细节简介

    WiFi6技术细节简介 WiFi的历史发展 WiFi历史发展中技术的迭代 WiFi6的新型技术优势 OFDMA 双向MU MMIO 多用户多输入输出 1024QAM 空间频率复用SR BSS Coloring WAP3 实际使用带来的用户体
  • docker: Error response from daemon: could not select device driver ““ with capabilities: [[gpu]].

    需要安装nvidia container toolkit或nvidia container runtime 包含nvidia container toolkit distribution etc os release echo ID VER
  • 使用 React Hooks + mock + antd构建一个完整且漂亮的 todoList

    实现效果 搭建项目 使用 create react app 快速创建一个项目 删除不必要的文件 保留文件如下 目录说明 index js 项目入口文件 index less 样式 mock js 模拟 todo 数据 TodoList js
  • 6基于二阶锥规划的主动配电网最优潮流求解

    matlab代码 6 基于二阶锥规划的主动配电网最优潮流求解 参考文献 主动配电网多源协同运行优化研究 乔珊 摘要 最优潮流研究在配 电网规划运行 中不可或缺 且在大量分布式能源接入 的主动配 电网环境下尤 为重要 传统的启发式算法 在全局
  • statsmodels.regression.linear_model.RegressionResults

    statsmodels regression linear model RegressionResults class statsmodels regression linear model RegressionResults model
  • vue上传文件夹,将file类型转为binary类型传参到后台

  • ES6-promise小技巧

    Promise all 从Promise all返回的主promise在所有成员promise都完成后才会执行 如果这些promise中有任何一个被拒绝 reject error 住promise就会被拒绝 并丢弃来自其他所有promise
  • 【Jupyter Notebook】安装及使用

    知识目录 前言 一 Jupyter Notebook安装使用 1 1 Jupyter Notebook的三种打开方式 1 点击Anaconda Prompt打开 2 点击Jupyter Notebook打开 3 使用Powershell打开
  • [计算机毕业设计]机器学习的数据驱动股票价格预测

    前言 大四是整个大学期间最忙碌的时光 一边要忙着准备考研 考公 考教资或者实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度的 对本科同学来说是充满挑战 为帮助大
  • 算法设计与分析——0/1背包问题

    问题描述 给定n个重量为 w1 w2 wn 价值为 v1 v2 vn 的物品和一个容量为C的背包 0 1背包问题是求这些物品中的一个 最有价值的子集 并且能够装入背包中 基本算法思想 暴力法 用暴力法解决0 1背包问题 需要考虑给定n个物品
  • 概率密度函数

    概率密度函数 Probability Density Function 简称PDF 是描述随机变量的概率分布的函数 它对于连续型随机变量来说是非常重要的概念 PDF可以用来描述变量在不同取值上的概率分布情况 对于一个连续型随机变量X 其概率
  • 记忆化搜索 (蒟蒻练习生)

    定义 记忆化搜索是一种通过记录已经遍历过的状态的信息 从而避免对同一状态重复遍历的搜索实现方式 因为记忆化搜索确保了每个状态只访问一次 它也是一种常见的动态规划实现方式 引入 题目见 NOIP2005 采药 朴素的 DFS 做法 很容易实现
  • Python web自动化测试 —— 文件上传

    文件上传三种方式 一 查看元素标签 如果是input 则可以参照文本框输入的形式进行文件上传 方法 和用户输入是一样的 使用send keys 1 2 3 4 5 步骤 1 找到定位元素 2 输入文件路径 ele driver find e
  • ios android 字体大小,并排文字在ios上字体变大,安卓上正常显示

    IOS页面 安卓页面 复现代码 公告 疑情公告 notice notice export default data return notice 中民筑友码垛机作业区域一号工位发 疑似闯入行为中民筑友码垛机作业区域一号工位发 疑似闯入行为 发
  • Golang中结构体Struct

    前言 这里总结的Golang 笔记只适合有点编程基础的人看 比如Java 往期内容 Golang学习 day1 变量 类型 Golang学习 指针 循环控制相关 循环结构控制 包函数的使用 异常处理 数组 老奶奶可以看懂的切片 老奶奶可以看
  • C++之extern和static用法和区别

    目录 声明和定义的区别 关键字extern 作用 用法总结 关键字static 全局变量和全局静态变量区别 局部静态变量 静态函数 声明和定义的区别 变量定义 用于为变量分配存储空间 还可为变量指定初始值 程序中 变量有且仅有一个定义 变量