【C/C++面試必備】volatile 關鍵字 - 有解無憂

文章推薦指數: 80 %
投票人數:10人

volatile 意思是易變的,是一種型別修飾符,在C/C++中用來阻止編譯器因誤認某段代碼無法被代碼本身所改變,而造成的過度優化,編譯器每次讀取volatile ... 菜單 網站主頁 前端設計 後端開發 .NET開發 軟體設計 企業開發 區塊鏈 移動端開發 軟體工程 資料庫 作業系統 其他 主頁 > 軟體設計 > 【C/C++面試必備】volatile關鍵字 【C/C++面試必備】volatile關鍵字 2021-07-2308:36:48軟體設計 🎈作者:Linux猿 🎈簡介:CSDN博客專家🏆,C/C++、面試、刷題、演算法盡管咨詢我,關注我,有問題私聊! 🎈關注專欄:C/C++面試通關集錦(優質好文持續更新中……)🚀 本文來講解一下C/C++中的關鍵字volatile,在日常的使用中很少使用到,但是,在面試中經常被提起,下面具體來看一下, volatile的作用是什么呢? volatile意思是易變的,是一種型別修飾符,在C/C++中用來阻止編譯器因誤認某段代碼無法被代碼本身所改變,而造成的過度優化,編譯器每次讀取volatile定義的變數時,都從記憶體地址處重新取值, 這里就有點疑問了,難道編譯器取變數的值不是從記憶體處取嗎? 并不全是,編譯器有時候會從暫存器處取變數的值,而不是每次都從記憶體中取,因為編譯器認為變數并沒有變化,所以認為暫存器里的值是最新的,另外,通常來說,訪問暫存器比訪問記憶體要快很多,編譯器通常為了效率,可能會讀取暫存器中的變數,但是,變數在記憶體中的值可能會被其它元素修改,比如:硬體或其它執行緒等, 來看一個實際的例子: #include intmain(){ constintvalue=10; int*ptr=(int*)&value; printf("初始值:%d\n",value); *ptr=100; printf("修改后的值:%d\n",value); return0; } 編譯程式,執行命令: linuxy@linuxy:~/volatile$gccmain.c-omain 運行后輸出: linuxy@linuxy:~/volatile$gccmain.c-omain linuxy@linuxy:~/volatile$./main 初始值:10 修改后的值:100 linuxy@linuxy:~/volatile$ 可以看到value的值變化了, 接下來再看一下編譯時添加-O引數優化的情況,執行命令gcc-Omain.c-omain, 輸出結果為: linuxy@linuxy:~/volatile$gcc-Omain.c-omain linuxy@linuxy:~/volatile$./main 初始值:10 修改后的值:10 linuxy@linuxy:~/volatile$ 可以看到添加-O引數優化后,value的值并沒有變化,這里就有問題了,是因為添加了-O引數,編譯器對代碼進行了優化,忽略了對變數value值的更改, -O引數: 使用該引數,編譯器會嘗試減少代碼大小和執行時間,但不執行需要占用大量編譯時間的優化,優化編譯需要占用更多的時間,對于大型函式需要占用更大的記憶體, 來看一下上面例子優化前和優化后代碼大小的對比: linuxy@linuxy:~/volatile$gccmain.c-omain linuxy@linuxy:~/volatile$ls-almain -rwxrwxr-x1linuxylinuxy167527月1814:38main linuxy@linuxy:~/volatile$gcc-Omain.c-omain linuxy@linuxy:~/volatile$ls-almain -rwxrwxr-x1linuxylinuxy167047月1814:38main linuxy@linuxy:~/volatile$ 可以看到,優化后檔案變小了, 那再看一下給上面的代碼添加上volatile關鍵字后會怎樣? #include intmain(){ volatileconstintvalue=10; int*ptr=(int*)&value; printf("初始值:%d\n",value); *ptr=100; printf("修改后的值:%d\n",value); return0; } 執行命令編譯程式: linuxy@linuxy:~/volatile$gcc-Omain.c-omain 輸出為: linuxy@linuxy:~/volatile$gcc-Omain.c-omain linuxy@linuxy:~/volatile$./main 初始值:10 修改后的值:100 linuxy@linuxy:~/volatile$ 可以看到,即使添加了-O引數優化程式,value的值依然被改變了, 最后,看一下volatile是怎樣使用的, 1.修飾普通變數 volatile型別變數 型別volatile變數 volatile放置到型別前后都可以,例如: #include intmain(){ volatileinta=10; intvolatileb=20; printf("a=%d\nb=%d\n",a,b); } 編譯后輸出: linuxy@linuxy:~/volatile$gcc-omainmain.c linuxy@linuxy:~/volatile$./main a=10 b=20 linuxy@linuxy:~/volatile$ 2.修飾指標 修飾指標和const類似(volatile和const都是型別修飾符),有三種形式: volatileint*p; int*volatilep; volatile型別*volatile變數; 看一下具體的代碼: #include intmain(){ inta=10; volatileint*p=&a; int*volatileq=&a; volatileint*volatilex=&a; printf("*p=%d\n*q=%d\n*x=%d\n",*p,*q,*x); } 編譯后輸出為: linuxy@linuxy:~/volatile$gcc-omainmain.c linuxy@linuxy:~/volatile$./main *p=10 *q=10 *x=10 linuxy@linuxy:~/volatile$ 3.作為函式引數 作為函式引數需要注意,例如: intsquare(volatileint*ptr) { return*ptr**ptr; } 編譯器處理的邏輯類似于以下情況: intsquare(volatileint*ptr) { inta,b; a=*ptr; b=*ptr; returna*b; } 因為ptr被宣告為volatile,所以a和b的值可能是不一樣的,所以最好采用如下這種方式: longsquare(volatileint*ptr) { inta; a=*ptr; returna*a; } 參考文獻: [1]https://stackoverflow.com/questions/4437527/why-do-we-use-volatile-keyword [2]https://www.geeksforgeeks.org/understanding-volatile-qualifier-in-c/ 🎈歡迎小伙伴們點贊👍、收藏?、留言💬 轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/289656.html 標籤:其他 上一篇:51單片機可以做什么實用的產品?下一篇:10W+字C語言硬核總結(一),值得閱讀收藏! 標籤雲 其他(123570)Java(13369)Python(12731)C(7545)區塊鏈(7372)JavaScript(7059)基礎類(6313)AI(6244)腳本語言(PerlPython)(5129)非技術區(4971)Android(4120)MySQL(4012)Linux(3394)C語言(3288)C++語言(3117)Java相關(2746)疑難問題(2699)單片機工控(2479)Web開發(1951)網絡通信(1793)數據庫相關(1767)VB基礎類(1755)PHP(1727)開發(1646)系統維護與使用區(1617).NETCore(1586)基礎和管理(1579)JavaEE(1566)C++(1527)專題技術討論區(1515)Windows客戶端使用(1484)HtmlCss(1466)ASP.NET(1428)Unity3D(1354)VCL組件開發及應用(1353)HTML(CSS)(1220)其他技術討論專區(1200)WindowsServer(1192).NET技术(1165)交換及路由技術(1149)語言基礎算法系統設計(1133)WindowsSDKAPI(1124)界面(1088)JavaSE(1075)Qt(1074)VBA(1048)新手樂園(1016)其他開發語言(947)Go(907)HTML5(901)新技術前沿(898)硬件設計(872)區塊鏈技術(860)網絡編程(857)非技術版(846)一般軟件使用(839)網絡協議與配置(835)Eclipse(790)Spark(750)下載資源懸賞專區(743) 熱門瀏覽 面試突擊第一季,第二季,第三季 第一季必考https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746第二季分布式https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro...... uj5u.com2020-09-1005:35:24more 第三單元作業總結 1.前言這應該是本學期最后一次寫作業總結了吧。

總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。

雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。

雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。

2.作業程序總結相比前兩個單元,此單...... uj5u.com2020-09-1005:35:41more 北航OO(2020)第四單元博客作業暨課程總結博客 北航OO(2020)第四單元博客作業暨課程總結博客本單元作業的架構設計在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。

考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。

本單元我...... uj5u.com2020-09-1005:35:48more BUAA_OO_第四單元 一、UML決議器設計? 先看下題目:第四單元實作一個基于JDK8帶有效性檢查的UML(UnifiedModelingLanguage)類圖,順序圖,狀態圖分析器MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成...... uj5u.com2020-09-1005:35:54more 6.1邏輯運算子 邏輯運算子1. &&短路與運算式1&&運算式201.運算式1為true并且運算式2也為true整體回傳為true02.運算式1為false,將不會執行運算式2整體回傳為false03.只要有一個運算式為false整體回傳為false2. ||短路或運算式1||運算式2...... uj5u.com2020-09-1005:35:56more BUAAOO第四單元&課程總結 1.第四單元:StarUml檔案決議本單元采用了圖模型決議UML。

UML檔案可以抽象為圖、子圖、邊的邏輯結構。

在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。

采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。

這里借鑒了一些...... uj5u.com2020-09-1005:36:06more 談談我對C#多型的理解 面向物件三要素:封裝、繼承、多型。

封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。

今天,我們就來講講多型的理解。

我們應該經常會看到面試題目:請談談對多型的理解。

其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。

具體實作方式有三種。

一、多載多載很簡單。

p...... uj5u.com2020-09-1005:36:09more Python資料驅動工具:DDT 背景python的unittest沒有自帶資料驅動功能。

所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。

DDT是“Data-DrivenTests”的縮寫。

資料:http://ddt.readthedocs.io/en/latest/使用方法dd....... uj5u.com2020-09-1005:36:13more Python里面的xlrd模塊詳解 那我就一下面積個問題對xlrd模塊進行學習一下:1.什么是xlrd模塊?2.為什么使用xlrd模塊?3.怎樣使用xlrd模塊?1.什么是xlrd模塊??python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。

今天就先來說一下xl...... uj5u.com2020-09-1005:36:28more 當我們創建HashMap時,底層到底做了什么? jdk1.7中的底層實作程序(底層基于陣列+鏈表)在我們newHashMap()時,底層創建了默認長度為16的一維陣列Entry[]table。

當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候:首先,呼叫key1所在類的hashCode()計算key1...... uj5u.com2020-09-1005:36:38more 最新发布 想在$(document).ready()中使用函式 我有一個類似的問題之前,我的問題是關于如何在網路瀏覽器控制臺中訪問所有的JavaScript函式,即使它們在window.onload=function(){//codeandfunctions}內,但這次我想用jQu... uj5u.com2021-10-1615:31:25more 在AndroidStudio中允許HTTP下載 我在AndroidStudio中得到了以下錯誤:>Couldnotdownloadbuilder-4.1.2.jar(com.android.tools.build:builder:4.1.2) >無法下載builder-4.1.2.jar(com.android.tools.... uj5u.com2021-10-1615:31:06more 如何抑制gradle關于DeprecatedGradle特性的警告? 我使用的是最新的Gradlev7.2。

當我編譯的時候,它給了我一個警告... uj5u.com2021-10-1615:30:48more Gradle7.2Java17Build問題java.lang.NullPointerException。

無法 >Task:compileJava 注意:有些輸入檔案使用或覆寫了已廢棄的API。

注意:用-Xlint:deprecationfor詳細資訊進行重新編譯。

在編譯器(17)中發生了一個例外。

請通過Java錯誤... uj5u.com2021-10-1615:30:05more 為什么我在JUnit4中得到這個例外? 我是JUnit測驗和Gradle的新手,我試著做了我的第一個簡單的測驗,但它們并不作業。

這是我的測驗代碼:這是我的測驗代碼。

importorg.junit.Test; importstaticorg.junit.Ass... uj5u.com2021-10-1615:28:38more 在模擬類中使用pytest夾具 我需要使用一個夾具,在一個將用于模擬第三方庫的類中準備一些資料。

現在,我有一個相當于這樣的方案:) deffile(tmpdir_factory)。

""創建一個模擬檔案的長程序。

""。

.... uj5u.com2021-10-1615:27:47more 不能在型別引數化方法中隱含地將子類轉換為父類 我最近不得不幫助解決某人在從泛型方法中回傳時遇到的問題,雖然有多個問題需要解決,但我理解并能解釋所有問題--除了讓編譯器接受回傳型別這一最后障礙。

盡管我最終成功地讓程... uj5u.com2021-10-1615:27:39more JavaObjectMapper.readValue將通用型別變成LinkedHashMap @Service publicclassPokemonManagerimplementsPokemonService{ privateHttpResponsegetStringHttpResponseByUrl(finalStringurl){ HttpCli... uj5u.com2021-10-1615:26:15more 如何創建一個通用結構? 我如何構建一個通用結構? 我試過: typeSafeSet[typeT]struct{ 值map[T]boolbool? } 我希望能夠做到例如我希望能夠做到例如 SafeSet{Values:make(map[net.Co... uj5u.com2021-10-1615:25:33more 通用類在mutableMap中的轉換 在我的應用程式中,我想做這樣的事情:在我的應用程式中,我想做這樣的事情。

interfaceBinder/span>{ funbind(binding。

VB,item:T) }... uj5u.com2021-10-1615:23:51more 友情鏈接 有解無憂



請為這篇文章評分?