新手BUG:函數中 static 變量的賦值語句只會執行一次

???????在 C++ 函數中使用 static 變量時,很多新手會陷入一個認知誤區:認為變量的初始化語句會在每次函數調用時執行。比如在

bool?funcA()?{?//?Q:多次調用funcA,funcB會被執行幾次?//?A:1次static?bool?value?=?funcB();?//?Q:多次調用funcA,funcC會被執行幾次?//?A:n次static?bool?value2?=?false;value2?=?funcC();?return?value;?
}

這類代碼中,新手往往預期funcB()會隨funcA()的每次調用而執行,卻發現返回值永遠是第一次初始化的結果。今天就來拆解這個隱蔽的陷阱。

一、問題代碼實測

先看一段模擬實際開發場景的代碼:

#include?<iostream>?
#include?<chrono>?
#include?<thread>?
?
//?模擬一個會返回不同結果的函數?
bool?funcB()?{?static?int?count?=?0;?count++;?std::cout?<<?"funcB被調用,第"?<<?count?<<?"次執行"?<<?std::endl;?//?每次調用返回相反的布爾值?return?count?%?2?==?0;?
}?
?
//?新手編寫的函數:錯誤理解static變量初始化時機?
bool?funcA()?{?//?預期:每次調用funcA都執行funcB(),返回最新結果?static?bool?value?=?funcB();??return?value;?
}?
?
int?main()?{?std::cout?<<?"第一次調用funcA:"?<<?std::boolalpha?<<?funcA()?<<?std::endl;?std::this_thread::sleep_for(std::chrono::seconds(1));?std::cout?<<?"第二次調用funcA:"?<<?std::boolalpha?<<?funcA()?<<?std::endl;?std::this_thread::sleep_for(std::chrono::seconds(1));?std::cout?<<?"第三次調用funcA:"?<<?std::boolalpha?<<?funcA()?<<?std::endl;?return?0;?
}
funcB被調用,第1次執行?
第一次調用funcA:false?
第二次調用funcA:false?
第三次調用funcA:false

結果分析? 從輸出可見,無論調用多少次funcA(),funcB()只在第一次執行,且funcA()始終返回第一次初始化的值false。這與新手預期的 “每次調用funcA()都觸發funcB(),返回不同結果” 完全不符。

二、原理

static 變量的初始化機制 函數內的 static 變量具有 首次初始化,全程復用的特性,其生命周期貫穿整個程序運行期,初始化僅在第一次進入函數作用域時執行

核心原因:C++ 標準規定,函數內的 static 變量屬于 “局部靜態對象”,其初始化具有 “惰性”—— 僅在首次使用時執行,且初始化完成后會永久保持當前值,直到程序結束才銷毀。

三、常見錯誤場景與正確寫法

1. 常見錯誤場景

  • 錯誤場景 1:依賴 static 變量獲取實時狀態

//?錯誤示例:想用static變量每次獲取當前時間
int?getCurrentSecond()?{static?int?sec?=?time(nullptr)?%?60;?//?僅第一次調用時獲取時間?return?sec;
}
  • 錯誤場景 2:在 static 初始化中處理動態邏輯

//?錯誤示例:期望每次調用都更新配置
bool?checkConfig()?{static?bool?isValid?=?loadConfigFromFile();?//?配置文件變化后不會重新加載return?isValid;
}

2. 正確寫法

移除 static 關鍵字。如果需要每次調用都執行初始化邏輯,應去掉 static 修飾

bool?funcA()?{bool?value?=?funcB();?//?每次調用都執行funcB()return?value;
}

運行結果(修正后)

funcB被調用,第1次執行
第一次調用funcA:false
funcB被調用,第2次執行
第二次調用funcA:true
funcB被調用,第3次執行
第三次調用funcA:false

四、static 變量的正確使用場景

1. 緩存計算結果

避免重復執行耗時操作

double?calculatePi()?{static?double?pi?=?computePiWithHighPrecision();?//?僅計算一次return?pi;
}

2. 單例模式實現

確保全局唯一實例

Logger&?getLogger()?{static?Logger?instance;?//?僅初始化一次return?instance;
}

3. 統計函數調用次數

記錄首次和總調用次數

int?countCalls()?{static?int?total?=?0;total++;return?total;
}

五、總結

???????函數內的 static 變量初始化具有 “一次性” 特點,其賦值語句僅在首次調用時執行,這與普通局部變量的 “每次調用重新初始化” 形成鮮明對比。

???????若需要保存跨函數調用的狀態(如累計計數),用 static 變量是比較好的選擇。

???????若需要每次調用都執行初始化邏輯(如獲取實時數據),就必須用普通局部變量。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92353.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92353.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92353.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python 基礎詳解:數據類型(Data Types)—— 程序的“數據基石”

一、引言&#xff1a;為什么數據類型如此重要&#xff1f;在 Python 編程中&#xff0c;數據類型決定了&#xff1a;數據的存儲方式可以對數據執行的操作數據的取值范圍不同類型之間的運算規則理解數據類型是編寫正確、高效程序的基礎。Python 是動態類型語言&#xff0c;雖然你…

WindowsLinux系統 安裝 CUDA 和 cuDNN

Windows安裝前的準備工作 檢查硬件兼容性&#xff1a;確認電腦顯卡為 NVIDIA GPU。通過快捷鍵 Win R 喚出“運行”&#xff0c;輸入“control /name Microsoft.DeviceManager”喚出“設備管理器”&#xff0c;點擊“顯示適配器”查看是否有 NVIDIA 字樣。 驗證 CUDA 支持性&a…

工業數采引擎-通信鏈路SOCKET

通信庫&#xff1a;DotNetty 封裝實現&#xff1a;TcpServer、TcpClient、Udp TCP協議特性&#xff1a;面向連接協議&#xff1b;每個新連接都會創建獨立的ChannelHandler實例&#xff1b;TcpHandler構造函數在每次客戶端連接時觸發 UDP協議特性&#xff1a;無連接協議&#…

PHP小白零基礎入門(附視頻教程)

概述 PHP是一種通用開源腳本語言&#xff0c;常用于服務器端Web開發&#xff0c;具有語法簡單、上手快等特點。視頻教程&#xff1a;https://pan.quark.cn/s/8f214c23301b 搭建開發環境&#xff1a; 選擇集成工具&#xff1a;可選擇XAMPP&#xff08;支持Windows/Mac/Linux…

驗證碼等待時間技術在酒店自助入住、美容自助與社區場景中的應用必要性研究—仙盟創夢IDE

代碼 代碼 完整<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>驗證碼倒計時</title><s…

Flask從入門到實戰:基礎、進階、項目架構與接口測試

本文將帶你從零開始掌握Flask框架&#xff0c;涵蓋基礎使用、進階技巧、項目架構設計&#xff0c;并提供完整的接口測試客戶端代碼。 目錄一、Flask基礎入門1.1 Flask簡介與安裝1.2 第一個Flask應用1.3 路由與請求處理1.4 請求與響應處理二、Flask進階使用2.1 模板引擎Jinja22.…

華為云產品圖解

框架圖核心說明: 1. 分層邏輯清晰 基礎設施層(IaaS):提供最基礎的計算(ECS/BMS)、存儲(OBS/EVS)、網絡(VPC/CDN)資源,是所有上層服務的 “物理底座”。 平臺服務層(PaaS):基于 IaaS 構建,提供容器編排(CCE)、數據庫(GaussDB)、大數據與 AI(ModelArts)、中…

Git 中如何回退到以前的提交記錄?

回答重點要在 Git 中回退到以前的提交記錄&#xff0c;你可以使用 git reset 命令。這個命令有三個常用選項來控制你想要回退的程度&#xff1a;1&#xff09; git reset --soft <commit> &#xff1a;僅修改 HEAD 指針&#xff0c;不修改索引和工作區內容。2&#xff09…

JavaWeb03——基礎標簽及樣式(表單)(黑馬視頻筆記)

1.表單標簽 及 表單屬性表單標簽是 &#xff1a;<form> 表單屬性有&#xff1a;action 和 method&#xff1b;action屬性&#xff1a;規定向何處發送表單數據。method屬性&#xff1a;規定用什么方法發送數據。&#xff08;get和post&#xff09;get:在發送的url后面拼接…

STM32的SPI通信(軟件讀寫W25Q64)

在了解完I2C通信后&#xff0c;不免會接觸到到SPI通信。而一開始&#xff0c;可能會覺得兩者好似沒什么區別。為什么要學SPI呢&#xff0c;I2C和SPI有什么區別呢。為此我詳細展開說說。1.什么是 SPI&#xff1f;SPI&#xff0c;全稱 Serial Peripheral Interface&#xff0c;中…

子詞分詞器(Byte Pair Encoding + WordPiece)

參考文章&#xff1a;子詞分詞器BPE和WordPiece理解_wordpeice-CSDN博客 子詞分詞器BPE和WordPiece理解_wordpeice-CSDN博客 WordPiece 和 BPE 的區別-CSDN博客 點互信息&#xff08;PMI&#xff09;和正點互信息&#xff08;PPMI&#xff09;-CSDN博客 https://zhuanlan.z…

阿里招AI產品運營

AI產品運營&#xff08;崗位信息已經過jobleap.cn授權&#xff0c;可在csdn發布&#xff09;靈犀互娛 廣州收錄時間&#xff1a; 2025年08月05日職位描述負責AI技術在游戲行業的應用與落地&#xff0c;專注于海外市場的運營中臺建設&#xff1b; 將結合AI技術與游戲行業特點&a…

Git 分支遷移完整指南(結合分支圖分析)

基于分支圖的當前狀態分析 分支圖關鍵信息解讀?分支結構?&#xff1a; #mermaid-svg-gc9SPnwlbrM2FzHf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-gc9SPnwlbrM2FzHf .error-icon{fill:#552222;}#mermaid-svg-…

小程序省市級聯組件使用

背景。uni-data-picker組件用起來不方便。調整后級聯效果欠佳&#xff0c;會關閉彈窗需要重新選擇。解決方案。讓cursor使用uniapp 原生組件生成懶加載省市級聯 <template><view class"picker-cascader"><view class"cascader-label">&l…

Java技術棧/面試題合集(8)-Redis篇

場景 Java入門、進階、強化、擴展、知識體系完善等知識點學習、性能優化、源碼分析專欄分享: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/140870227 通過對面試題進行系統的復習可以對Java體系的知識點進行查漏補缺。 注: 博客: 霸道流氓氣質-CSDN博…

川翔云電腦:引領開啟算力無邊界時代

一、何為云電腦&#xff1f;重新定義“主機”概念 云電腦將傳統本地計算機的核心硬件資源&#xff08;CPU、GPU、內存、硬盤等&#xff09;集中部署于遠程高性能數據中心&#xff0c;通過網絡技術將虛擬桌面實時傳輸到您的任意訪問設備上。 ??如同將高配主機裝入云端&#…

tc 介紹

目錄 1.背景 2. tc介紹 3. tc 丟包 1.背景 需要使用tc 構造丟包場景&#xff0c;注意tc 丟包不能確定丟棄的是否是payload 數據包&#xff0c;有可能丟棄 ack 包。 2. tc介紹 1. 無法正常使用 [rootpool-100-1-1-18 /]# [rootpool-100-1-1-18 /]# tc qdisc add dev swif…

LabVIEW注冊表操作

?本文圍繞LabVIEW中操作Windows 注冊表的 4 個 VI 展開&#xff0c;介紹其功能、使用場景等并對比&#xff0c;助力工程師高效運用注冊表交互功能。各 VI 功能說明&#xff08;一&#xff09;Write the Key功能&#xff1a;創建新注冊表鍵&#xff0c;設置其值&#xff0c;隨后…

阿里云部署若依后,瀏覽器能正常訪問,但是apifox和小程序訪問后報錯鏈接被重置

項目場景&#xff1a;阿里云部署若依后瀏覽器能正常通過https訪問,但是在apifox和小程序調用接口的時候生報錯E問題描述apifox報錯&#xff1a;curl報錯&#xff1a;通過curl可以清楚的看到通過域名是能準確的訪問到IP地址的&#xff0c;說明這個DNS是沒有問題的&#xff0c;但…

升級 Elasticsearch 到新的 AWS Java SDK

作者&#xff1a;來自 Elastic David Turner, Dianna Hohensee Elasticsearch 使用官方的 AWS Java SDK 集成了某些 Amazon Web Services (AWS) 功能。這些集成最早在近 10 年前發布的 Elasticsearch 2.0 版本中引入。 最近&#xff0c;AWS 宣布 Elasticsearch 過去十年使用的…