網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
前言
C/C++中的靜態(tài)變量,相信大多數(shù)人都用過,但你很可能用錯(cuò)了,包括你現(xiàn)在所在的項(xiàng)目中都可能埋著這個(gè)坑,不信我們往下看!
正文
我們先來看一段大家常寫的代碼,很簡(jiǎn)單,這段代碼沒啥坑:
#include <stdio.h>
int GetData()
{
static int a = 0;
return a++;
}
int main()
{
for (int i = 0; i < 100; ++i)
{
printf("%d\n", GetData());
}
}
大家都清楚,靜態(tài)變量只初始化一次,所以GetData調(diào)用了100次,打印的結(jié)果也是0-99,想必大家都很清楚 ,那請(qǐng)問GetData中初始化變量a的代碼只會(huì)執(zhí)行一次?是在哪個(gè)階段初始靜態(tài)局部變量a的?
想必大家都能回答上來,靜態(tài)局部變量a的生命周期從程序運(yùn)行開始就已經(jīng)存在并初始化了的,并非是在GetData函數(shù)中初始化的,但又不完全對(duì),我們看下一段代碼:
#include <stdio.h>
int GetA()
{
return 0;
}
int GetData()
{
static int a = GetA();
return a++;
}
int main()
{
for (int i = 0; i < 100; ++i)
{
printf("%d\n", GetData());
}
}
看了這段代碼,不知道大家有沒有懵逼?問題來了,請(qǐng)問GetA函數(shù)會(huì)被調(diào)用幾次?靜態(tài)局部變量a是在什么時(shí)候初始化的?給大家5秒鐘思考!
OK!靜態(tài)局部變量無(wú)論如何都只會(huì)初始化一次,這是沒有毛病的,但此時(shí)靜態(tài)局部變量a是在第一次調(diào)用GetData函數(shù)的時(shí)候才被初始化的,與前一個(gè)例子用常量初始化靜態(tài)變量并不相同,當(dāng)然生命周期還是從程序運(yùn)行開始到程序結(jié)束為止。
那編譯器是怎么初始化靜態(tài)變量a的呢?編譯器會(huì)改造GetData方法如下:
int GetData()
{
static bool init = false;
if (!init)
{
a = GetA();//a已經(jīng)被定義在全局了
init = true;
}
return a++;
}
這樣編譯器就可以保證靜態(tài)變量a在GetData函數(shù)內(nèi)只被初始化一次,但請(qǐng)問a的初始化是否線程安全?
當(dāng)然,不同編譯器的實(shí)現(xiàn)并不相同,有的編譯器會(huì)在初始化全局變量a的時(shí)候用上臨界區(qū)等,以保證初始化的線程安全,有的卻并沒有,當(dāng)然為了自己的代碼兼容性更強(qiáng),建議不要這樣寫,隨便換個(gè)方法都能替代。或者只使用常量去初始化靜態(tài)變量,這能保證線程安全!
總結(jié),編譯器在我們不知道的地方默默付出,大家要知道感恩!
原文鏈接:https://blog.csdn.net/Think88666/article/details/126004224
相關(guān)推薦
- 2022-05-07 Python?識(shí)別錄音并轉(zhuǎn)為文字的實(shí)現(xiàn)_python
- 2022-06-07 C語(yǔ)言非遞歸算法解決快速排序與歸并排序產(chǎn)生的棧溢出_C 語(yǔ)言
- 2022-05-13 C語(yǔ)言中的輸入與輸出
- 2022-11-08 Python?Panda中索引和選擇?series?的數(shù)據(jù)_python
- 2022-03-26 R語(yǔ)言基于Keras的MLP神經(jīng)網(wǎng)絡(luò)及環(huán)境搭建_R語(yǔ)言
- 2022-07-07 C語(yǔ)言數(shù)組快速入門詳細(xì)講解_C 語(yǔ)言
- 2022-05-03 詳解利用python-highcharts庫(kù)繪制交互式可視化圖表_python
- 2022-08-13 Linux新特性之btrfs文件系統(tǒng)
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支