前言
goto語句也稱為無條件轉移語句,其基本形式如下:
語句標號由一個有效地標識符和符號";"組成,其中,標識符的命名規則與變量名稱相同,即由字母、數字和底線組成,且第一個字元必須是字母或底線。執行goto語句後,程式就會跳到語句標號處,執行其後的語句。
通常goto語句與if條件語句連用,但是,goto語句在給程式帶來彈性的同時,也會使得使程式結構層次不清,而且不易讀,所以要合理運用該語句。
發現問題
我們常常碰到有在goto後面定義變量,linux下編譯不通過的問題(報錯訊息:crosses initialization of)。其實,只要注意一下就好了,今天問了一下公司前輩之後,也翻了些資料,記錄一下,加深記憶,也希望能對一些人有些許幫助。
錯誤範例程式碼:
#include <iostream> using namespace std; int main() { goto Exit; int a = 0; Exit: return 0; }
報錯:
[root@localhost c-c++]# g++ goto_study.cpp goto_study.cpp: In function 'int main()': goto_study.cpp:31: error: jump to label 'Exit' goto_study.cpp:29: error: from here goto_study.cpp:30: error: crosses initialization of 'int a'
正確寫法
直接上碼:
寫法一:
改變域,變成局部變數:int main() { goto Exit; { int a = 0; } Exit: return 0; }
寫法二白可以訪問!結果:
int main() { goto Exit; int a; a = 1; Exit: cout << "a = " << a << endl; return 0; }
研究
神奇的寫法
看到兩個可以編譯通過的寫法之後,最納悶的是寫法二為毛可以編譯通過,而且還能使用? ? ?
C++規定
參考[1][2]中提到了C++標準中的規定: > It is possible to transfer into a block, but not
in a way that bypasses declarations with initialization. A program that jumps
from a point where a local variable with automatic storage duration is not in
scope to a point where it is in scope is ill-formed unless the variable has POD
type (3.9) and is declared without an initializer.
意思是說:如果一個程式的執行路徑從程式碼中的點A(某個局部變數x還未定義)跳到程式碼中另一點B(該局部變量x已定義,定義的時候有初始化),那麼編譯器就會報錯。這樣的跳躍可以是因為執行goto語句,或是switch-case造成的。所以,在寫法二中a是int類型,是POD類型,沒有初始化,所以編譯通過。但是,很明顯:如果去使用這個變數a的時候,結果是未知的,就像前輩說的,沒有意義,不如不支持!那如果只在局部使用,完全可以用花括號括起來!網路上也有人說到,C++規範雖然沒有明確說明這樣是錯誤的,但是變數的域的規定其實是隱性說這種做法是不可取的,見參考[4]。
隱性說明
Goto can't skip over definitions of variables, because those variables would
not exist after the jump, since lifetime of variable starts at the point of
definition. The specification does not seem to explicitly mention goto must not
do that, but it is implied in what is said about variable lifetime.
-fpermissive標記
參考[4]中提到,g++編譯器預設是檢查的,自己可以設定編譯器的這個標記變成警告,未實踐! ! !
查了一下資料-fpermissive標記的作用是: 把程式碼的語法錯誤當作警告,並繼續編譯進程,所以就安全起見,這個角度就不要想了,還是老實碼磚!
POD類型
參考[3],依照上面C++規定的說法,只要是POD型,且沒有初始化都是可以編譯通過的。
看一段程式碼:
[root@localhost c-c++]# g++ goto_study.cpp [root@localhost c-c++]# ./a.out a = 1259648
結果:
#include <iostream> using namespace std; class A{ public: // 注意:和B不同的是有构造和析构函数, 所以编译报错 A(){} ~A(){} void testA(){ cout << "A::test." << endl; } }; class B{ public: void testB(){ cout << "B::test." << endl; } }; int main() { goto Exit; // int a = 1; // windows ok.linux failed! //A classA; // failed: B classB; // success: classB.testB(); Exit: classB.testB(); return 0; }
小結:
A classA一句在windows和linux均編譯不通過!因為A有構造和析構函數,不滿足條件;
3、至於int a = 1;這樣的寫法在windows(msvc)下面能夠通過就與C++規範不符了,求解釋! ! !
以下是POD類型(還是看英文吧):
1、int, char, wchar_t, bool, float, double是POD類型,這些類型的long/short and
signed/unsigned版本也是;
2、 指標(包括函數指標和成員指標)都是POD型別;
5、POD型別的class,struct和union也是。但要求所有的成員是public,且沒有基底類,沒有建構、析構函數和虛函數。靜態成員在這些規則下也是。
總結
1、最好不要用goto;
2.goto後面不要跳過定義和初始化的變量,如果是POD類型可以先申明再定義,是不會編譯報錯的。但不建議這麼使用,可以看到如果執行語句跳過了賦值語句,那麼變量的值是未知的,存在危險性;
3、goto後面如果是局部的變量,可以用花括號括起來構成一個局部域,就安全了。
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流。
更多相關文章請關注PHP中文網(www.php.cn)!

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

C#.NET面試問題和答案包括基礎知識、核心概念和高級用法。 1)基礎知識:C#是微軟開發的面向對象語言,主要用於.NET框架。 2)核心概念:委託和事件允許動態綁定方法,LINQ提供強大查詢功能。 3)高級用法:異步編程提高響應性,表達式樹用於動態代碼構建。

C#.NET是構建微服務的熱門選擇,因為其生態系統強大且支持豐富。 1)使用ASP.NETCore創建RESTfulAPI,處理訂單創建和查詢。 2)利用gRPC實現微服務間的高效通信,定義和實現訂單服務。 3)通過Docker容器化微服務,簡化部署和管理。

C#和.NET的安全最佳實踐包括輸入驗證、輸出編碼、異常處理、以及身份驗證和授權。 1)使用正則表達式或內置方法驗證輸入,防止惡意數據進入系統。 2)輸出編碼防止XSS攻擊,使用HttpUtility.HtmlEncode方法。 3)異常處理避免信息洩露,記錄錯誤但不返回詳細信息給用戶。 4)使用ASP.NETIdentity和Claims-based授權保護應用免受未授權訪問。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver CS6
視覺化網頁開發工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

禪工作室 13.0.1
強大的PHP整合開發環境

WebStorm Mac版
好用的JavaScript開發工具