首頁 後端開發 C#.Net教程 C++跳轉語句之Goto對變數定義的影響詳解

C++跳轉語句之Goto對變數定義的影響詳解

Dec 14, 2016 pm 05:15 PM

前言

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 &#39;int main()&#39;:
goto_study.cpp:31: error: jump to label &#39;Exit&#39;
goto_study.cpp:29: error: from here
goto_study.cpp:30: error: crosses initialization of &#39;int a&#39;
登入後複製

   

正確寫法

正確寫法


直接上碼:

寫法一:

改變域,變成局部變數:

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)! 


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1322
25
PHP教程
1270
29
C# 教程
1249
24
如何在Python中定義變數? 如何在Python中定義變數? Jun 04, 2023 am 10:02 AM

在Python中,變數可以理解為儲存資料的容器。當我們需要使用或操作數據時,可以透過定義變數來儲存數據,從而方便地調用和處理這些數據。以下將介紹Python中定義變數的方法。一、命名規則在Python中,變數的命名規則非常靈活,通常需要遵循以下規則:變數名稱由字母、底線和數字組成,首位不能為數字。變數名可以使用大小寫字母,但Python是區分大小寫的。變數名

c語言中goto語句的意思是什麼 c語言中goto語句的意思是什麼 Dec 22, 2022 pm 06:00 PM

在c語言中,goto語句被稱為無條件轉移語句,允許把控制無條件轉移到同一函數內的被標記的語句;語法“goto label;...label: statement;”,其中label可以是任何除C關鍵字以外的純文本,它可以設定在C程式中goto語句的前面或後面。

go語言中goto怎麼用 go語言中goto怎麼用 Nov 23, 2022 pm 06:40 PM

在go語言中,goto語句用於無條件跳轉,可以無條件地轉移到程式中指定的行;它透過標籤進行程式碼間的無條件跳轉。 goto後面接著一個標籤,這個標籤的意義是告訴Go程式下一步要執行哪行的程式碼,語法「goto 標籤;... ...標籤: 表達式;」。 goto打破原有程式碼執行順序,直接跳到指定行執行程式碼;goto語句通常與條件語句配合使用,可用來實現條件轉移、構成迴圈、跳出迴圈體等功能。

Golang函數的變數定義時的賦值方法與差異 Golang函數的變數定義時的賦值方法與差異 May 17, 2023 pm 07:01 PM

Golang是一種快速、高效、現代化的程式語言,它在編譯時會自動檢查類型,並且具有並發性和記憶體安全性等特點,因此被越來越多的開發者所青睞。在Golang中,我們經常需要使用函數來封裝業務邏輯,而函數中的變數定義時的賦值方法是一個常見的問題,本文將詳細講解這個問題並分析其中的差異。變數定義在Golang中,可以使用var和:=兩種方式來定義變數。其中,var方

如何在PHP中定義變數和常數 如何在PHP中定義變數和常數 May 11, 2023 pm 04:03 PM

PHP是一種被廣泛使用的程式語言,具有卓越的可擴展性和實用性。在PHP中,變數和常數是兩種十分重要的概念,它們可以用來儲存和表示值以及儲存重要的資訊。在這篇文章中,我們將會詳細介紹如何在PHP中定義變數和常數,以幫助初學者快速上手。一、定義變數變數是用於儲存值的名字或識別碼。在PHP中,變數的定義可以分為三個步驟:變數的宣告、變數的賦值、使用變數。下面我們詳

提升程式效率:掌握Go語言跳轉語句的應用 提升程式效率:掌握Go語言跳轉語句的應用 Mar 21, 2024 pm 05:03 PM

提升程式效率:掌握Go語言跳躍語句的應用在Go語言程式設計中,跳躍語句是常用的控制語句,能夠幫助我們實現程式碼邏輯的跳躍與控制,提升程式效率。掌握跳轉語句的使用可以讓我們更靈活地處理各種複雜的邏輯,減少程式碼冗餘,提高程式碼可讀性和執行效率。本文將介紹Go語言中常用的跳躍語句,並透過具體的程式碼範例來說明它們的應用。 1.break語句break語句用於跳出目前循環

如何解決Python的函數變數重複定義錯誤? 如何解決Python的函數變數重複定義錯誤? Jun 25, 2023 am 11:59 AM

Python的函數變數重複定義錯誤是一個常見問題,當一個函數中重複定義了相同名稱的變數時,Python會拋出「localvariable'xxxx'redefined」錯誤。這個錯誤通常是由於函數內部的變數名和外部的變數名重複所導致的。在Python中,變數作用域分為局部作用域和全域作用域,當在一個函數中定義變數時,變數預設為局部變量,並且只能在該函數

Golang變數定義的規格和技巧 Golang變數定義的規格和技巧 Jan 13, 2024 pm 03:43 PM

Golang中變數定義的規範與技巧概述:在Golang中,變數是程式中最基本的資料儲存單元。正確使用變數定義的規格和技巧可以提高程式碼的可讀性、可維護性和效能。本文將介紹一些Golang中變數定義的規格和技巧,並提供具體的程式碼範例。變數的命名規範:在Golang中,變數的命名是有一定規範的。變數名應該使用駝峰命名法,首字母小寫。如果是私有變量,應該使用駝峰命名

See all articles