網(wǎng)站首頁 編程語言 正文
前言
C/C++中的靜態(tài)變量,相信大多數(shù)人都用過,但你很可能用錯了,包括你現(xià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,想必大家都很清楚 ,那請問GetData中初始化變量a的代碼只會執(zhí)行一次?是在哪個階段初始靜態(tài)局部變量a的?
想必大家都能回答上來,靜態(tài)局部變量a的生命周期從程序運行開始就已經(jīng)存在并初始化了的,并非是在GetData函數(shù)中初始化的,但又不完全對,我們看下一段代碼:
#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());
}
}
看了這段代碼,不知道大家有沒有懵逼?問題來了,請問GetA函數(shù)會被調(diào)用幾次?靜態(tài)局部變量a是在什么時候初始化的?給大家5秒鐘思考!
OK!靜態(tài)局部變量無論如何都只會初始化一次,這是沒有毛病的,但此時靜態(tài)局部變量a是在第一次調(diào)用GetData函數(shù)的時候才被初始化的,與前一個例子用常量初始化靜態(tài)變量并不相同,當(dāng)然生命周期還是從程序運行開始到程序結(jié)束為止。
那編譯器是怎么初始化靜態(tài)變量a的呢?編譯器會改造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)只被初始化一次,但請問a的初始化是否線程安全?
當(dāng)然,不同編譯器的實現(xiàn)并不相同,有的編譯器會在初始化全局變量a的時候用上臨界區(qū)等,以保證初始化的線程安全,有的卻并沒有,當(dāng)然為了自己的代碼兼容性更強,建議不要這樣寫,隨便換個方法都能替代。或者只使用常量去初始化靜態(tài)變量,這能保證線程安全!
總結(jié),編譯器在我們不知道的地方默默付出,大家要知道感恩!
原文鏈接:https://blog.csdn.net/Think88666/article/details/126004224
相關(guān)推薦
- 2023-12-25 MybatisPlus的BaseMapper和Wrapper使用
- 2023-12-11 IOC和AOP概念簡述
- 2022-10-14 Redis常見分布鎖的原理和實現(xiàn)_Redis
- 2022-05-20 jmeter連接數(shù)據(jù)庫The driver has not received any packets
- 2022-08-19 Android實現(xiàn)九宮格抽獎_Android
- 2022-12-12 C語言實現(xiàn)循環(huán)打印星號圖形再鏤空_C 語言
- 2022-12-08 利用C語言編寫一個無限循環(huán)語句_C 語言
- 2022-07-21 List<Map<String, Object>>使用
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支