本章通过问答方式明晰两个关键字及其作用。

Q1:对于int x;,不加extern关键字他就是个未赋初值的定义,但是如果加了static或者extern都可以表示这仅是一个声明吗?

A:不是的,具体情况如下:

int x; 是一个定义,它为 x 分配了存储空间,但没有显式地初始化。如果 x 是全局变量或静态变量,它会被隐式初始化为0。类内或函数内局部变量是一个随机数,尽量避免这种情况;

extern int x; 是一个声明,它告诉编译器 x 是一个整型变量,但并未为其分配存储空间。你需要在其他地方定义 x。

static int x; 可以是声明或定义,具体取决于上下文。如果它出现在函数内部,那么它是一个定义,并且 x 只能在该函数内部访问。如果它出现在全局范围内,那么它是一个定义,并且 x 只能在当前文件内访问。如果它出现在类内部,那么它是一个声明,并且你需要在类外定义并初始化这个静态成员变量。

Q2:static是可以用来标记本文件作用域的吗?

A: 是的,对于extern关键字,它可以通过extern int x;说明x在其他文件中已定义,请到其他地方寻找,但如果同时赋值,那么extern关键字的作用就被抵消了,如extern int x = 1等价于int x = 1;

而对于static int x;说明x仅在本文件中定义,其他文件无法访问。

Q3:为什么类内的static只是一个声明,定义和赋初值都需要在类外实现?

A:

1.根据primer第4版的解释,static局部对象必须遵守[确保不迟于在程序执行流程第一次经过该对象的定义语句时进行初始化]的这一个原则。

2、同时,我们知道类内部的执行顺序并不是按行次序执行的,而是按对象调用执行的

3、以上两者决定了一个问题: 如果在类内定义,那么不建立对象时,静态数据成员无法初始化,或初始化时间太迟。(可能原因之一]

4、再者,静态成员的生命周期是,一经建立便会存在与整个程序的生命周期内。而静态数据成员即属于类、也不属于类的原因便在此,在类内定义,会使其完全成为该类中的成员,也就是说,当建立复数人该类对象时,会再次声明并定义这静态变量的位置,且名字空间和作用域相同下,导致重名问题。(可能原因之二)

5、因此static的成员需要独立于类作定义

Q4:函数内定义的static变量出了函数作用域后还会存在吗?

A:

是的,函数内定义的静态变量在函数执行完毕后仍然存在。静态变量在程序执行期间只被初始化一次,并且它们的生命周期与程序的生命周期相同。这意味着,即使函数执行完毕,静态变量仍然存在,并且在下一次调用该函数时,它们将保留上一次调用时的值。

例如,下面这个函数 count 使用了一个静态变量 x 来记录它被调用的次数:

void count() {
static int x = 0;
x++;
cout << x << endl;
}

每次调用 count 函数时,x 的值都会增加1,并输出当前的值。即使函数执行完毕,x 仍然存在,并且在下一次调用 count 函数时,它将保留上一次调用时的值。即static int x = 0;只会在第一次调用count()函数时起效一次。

详解C++中的extern与static关键字的更多相关文章

  1. 从缓存入门到并发编程三要素详解 Java中 volatile 、final 等关键字解析案例

    引入高速缓存概念 在计算机在执行程序时,以指令为单位来执行,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入. 由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这 ...

  2. 【转】详解C#中的反射

    原帖链接点这里:详解C#中的反射   反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...

  3. 详解Webwork中Action 调用的方法

    详解Webwork中Action 调用的方法 从三方面介绍webwork action调用相关知识: 1.Webwork 获取和包装 web 参数 2.这部分框架类关系 3.DefaultAction ...

  4. 详解Java中的clone方法

    详解Java中的clone方法 参考:http://blog.csdn.net/zhangjg_blog/article/details/18369201/ 所谓的复制对象,首先要分配一个和源对象同样 ...

  5. 详解Python中re.sub--转载

    [背景] Python中的正则表达式方面的功能,很强大. 其中就包括re.sub,实现正则的替换. 功能很强大,所以导致用法稍微有点复杂. 所以当遇到稍微复杂的用法时候,就容易犯错. 所以此处,总结一 ...

  6. jQuery:详解jQuery中的事件(二)

    上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...

  7. 图文详解Unity3D中Material的Tiling和Offset是怎么回事

    图文详解Unity3D中Material的Tiling和Offset是怎么回事 Tiling和Offset概述 Tiling表示UV坐标的缩放倍数,Offset表示UV坐标的起始位置. 这样说当然是隔 ...

  8. 【转】详解JavaScript中的this

    ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...

  9. 深入详解SQL中的Null

    深入详解SQL中的Null NULL 在计算机和编程世界中表示的是未知,不确定.虽然中文翻译为 “空”, 但此空(null)非彼空(empty). Null表示的是一种未知状态,未来状态,比如小明兜里 ...

  10. java 乱码详解_jsp中pageEncoding、charset=UTF -8"、request.setCharacterEncoding("UTF-8")

    http://blog.csdn.net/qinysong/article/details/1179480 java 乱码详解__jsp中pageEncoding.charset=UTF -8&quo ...

随机推荐

  1. ajax高级(请求服务器脚本,数据库, ajxa xml文件)

    请求jsp与请求普通文件不通过的地方,请求jsp可能会传参,比如搜索,用户名,页码这些 html部分:<input type="text" id="txt1&quo ...

  2. 关于uniapp图片默认的空隙处理方案

    display:block; 或者 display:flex;

  3. Android studio SDK配置

    因为两个月前装过一次Android studio,所以完全按教程走不通. 已有Android studio的情况下,先在configue下配置SDK的位置,这里可能会报一个错,platforms不存在 ...

  4. SQL Server 手工 锁表、查询被锁表、解锁相关语句

    SQL Server 手工 锁表.查询被锁表.解锁相关语句 --锁表(其它事务不能读.更新.删除) BEGIN TRAN SELECT * FROM <表名> WITH(TABLOCKX) ...

  5. C语言程序设计基础 实验3 函数

    C语言程序设计基础 实验3 函数   一.实验目的 1. 理解函数的本质:模块化,实现代码复用 2. 掌握函数定义.声明.调用的语法 3. 理解并掌握函数的形参.实参,以及函数调用和返回的过程 4. ...

  6. Java使用Redis实现分布式锁

    1.概述 此处使用Redis的setNx命令和expire命令和del命令来实现分布式锁. 首先我们要知道, 我们的redis执行命令是队列方式的,并不存在多个命令同时运行,所有命令都是串行的访问.那 ...

  7. WebLogic & Kubernetes

    搭建kubernetes集群环境 安装前的规划 主机名 地址 角色 组件 k8s-master 192.168.56.118 k8s-master etcd.kube-apiserver.kube-c ...

  8. 利用网络复制安装额外域控制器、利用介质安装额外域控制器、安装RODC额外域控制器

    一.拥有多台域控制器的优势 1.分担用户身份验证的负担,改善用户登录的效率 2.容错功能:若有域控制器故障,此时仍然可以有其他正常的域控制器来继续提供服务,因此对用户的服务并不会停止 二.系统提供两种 ...

  9. 常见Dos命令学习

    Dos命令行 打开CMD方法 开始+系统+命令提示符(方便以管理员身份运行) Win+R 输入cmd 打开控制台(最常用) 在任意文件夹下,按住Shift键+鼠标右键点击,选择"在此处打开P ...

  10. python-实现动态web服务器

    # encoding=utf-8 import socket from multiprocessing import Process import re import sys # 设置静态文件根目录 ...