欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++中使用局部/全局變量初始值或默認(rèn)值問題

 更新時(shí)間:2024年08月21日 10:23:29   作者:江北一滴水  
這篇文章主要介紹了C/C++中使用局部/全局變量初始值或默認(rèn)值問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

在C語言中的全局變量和靜態(tài)變量都是會自動初始化為0,堆和棧中的局部變量不會初始化而擁有不可預(yù)測的值。

C++保證了所有對象與對象成員都會初始化,但其中基本數(shù)據(jù)類型的初始化還得依賴于構(gòu)造函數(shù)。

下文來詳細(xì)探討C風(fēng)格的”默認(rèn)初始化”行為,以及C++中成員變量的初始化規(guī)則。

一、初始化的語法

很多人至今不知道C++中如何正確地初始化一個(gè)變量,我們首先來解決語法的問題。

C語言中在聲明時(shí)用=即可完成初始化操作。但我們偏向于使用C++風(fēng)格(本文中均指面向?qū)ο蟪绦蛟O(shè)計(jì)風(fēng)格)來初始化內(nèi)置類型:

// C 風(fēng)格
int i = 3;
int arr[] = {1, 2, 3}; 
// C++ 風(fēng)格
int i(3);
int i = int(3);
int *p = new int(3);
int* arr = new int[3] {1, 2, 3};

在C語言中int a;表示聲明了整型a但未初始化,而C++中的對象總是會被初始化的,無論是否寫了圓括號或者是否寫了參數(shù)列表,例如:

int basic_var;      // 未初始化:應(yīng)用"默認(rèn)初始化"機(jī)制
CPerson person;     // 初始化:以空的參數(shù)列表調(diào)用構(gòu)造函數(shù)

二、默認(rèn)初始化規(guī)則

定義基本數(shù)據(jù)類型變量(單個(gè)值、數(shù)組)的同時(shí)可以指定初始值,如果未指定C++會去執(zhí)行默認(rèn)初始化(default-initialization)。 那么什么是”默認(rèn)初始化”呢?

  • 1.棧中的變量(函數(shù)體中的自動變量)和堆中的變量(動態(tài)內(nèi)存)會保有不確定的值;
  • 2.全局變量和靜態(tài)變量(包括局部靜態(tài)變量)會初始化為零;
  • 3.(lanyan注)函數(shù)體中的自動變量在有些編譯器下(我的是Clion2021.3),雖然在未初始化的情況下輸出也是0,但是編譯時(shí)會出現(xiàn)警告,所以這樣寫是不對的。

所以函數(shù)體中的變量定義是這樣的規(guī)則:

//C++中
int i;                    // 不確定值
int i = int();            // 0
int *p = new int;         // 不確定值
int *p = new int();       // 0

三、靜態(tài)和全局變量的初始化

未初始化的和初始化為零的靜態(tài)/全局變量編譯器是同樣對待的,把它們存儲在進(jìn)程的BSS段(這是全零的一段內(nèi)存空間)中。所以它們會被”默認(rèn)初始化”為零。

來看例子:

int g_var;
int *g_pointer;
static int g_static;
 
int main(){
    int l_var;
    int *l_pointer;
    static int l_static;
 
    cout<<g_var<<endl<<g_pointer<<endl<<g_static<<endl;
    cout<<l_var<<endl<<l_pointer<<endl<<l_static<<endl;
};

輸出:

0                   // 全局變量
0x0                 // 全局指針  
0                   // 全局靜態(tài)變量
32767               // 局部變量
0x7fff510cfa68      // 局部指針
0                   // 局部靜態(tài)變量

動態(tài)內(nèi)存中的變量在上述代碼中沒有給出,它們和局部變量(自動變量)具有相同的”默認(rèn)初始化”行為。

四、成員變量的初始化

成員變量分為成員對象和內(nèi)置類型成員,其中成員對象總是會被初始化的。而我們要做的就是在構(gòu)造函數(shù)中初始化其中的內(nèi)置類型成員。

class A{
public:
    int v;
};
A g_var;
 
int main(){
    A l_var;
    static A l_static;
    cout<<g_var.v<<' '<<l_var.v<<' '<<l_static.v<<endl;
    return 0;
}

輸出:

0 2407223 0

可見內(nèi)置類型的成員變量的”默認(rèn)初始化”行為取決于所在對象的存儲類型,而存儲類型對應(yīng)的默認(rèn)初始化規(guī)則是不變的。 所以為了避免不確定的初值,通常會在構(gòu)造函數(shù)中初始化所有內(nèi)置類型的成員。

Effective C++: Item 4一文討論了如何正確地在構(gòu)造函數(shù)中初始化數(shù)據(jù)成員。

這里就不展開了,直接給出一個(gè)正確的初始化寫法:

class A{
public:
    int v;
    A(): v(0);
};

五、封閉類嵌套成員的初始化

再來探討一下當(dāng)對象聚合發(fā)生時(shí)成員變量的”默認(rèn)初始化”行為,同樣還是只關(guān)注于基本數(shù)據(jù)類型的成員。

class A{
public:
    int v;
};
 
class B{
public:
    int v;
    A a;
};
 
B g_var;
int main(){
    B l_var;
    cout<<g_var.v<<' '<<g_var.a.v<<endl;
    cout<<l_var.v<<' '<<l_var.a.v<<endl;
    return 0;
}

結(jié)果:

0 0
43224321 -1610612736

規(guī)則還是是一樣的,默認(rèn)初始化行為取決于它所屬對象的存儲類型。

封閉類(Enclosing)中成員對象的內(nèi)置類型成員變量的”默認(rèn)初始化”行為取決于當(dāng)前封閉類對象的存儲類型,而存儲類型對應(yīng)的默認(rèn)初始化規(guī)則仍然是不變的。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++容器適配器的概念與示例

    C++容器適配器的概念與示例

    C++?STL(標(biāo)準(zhǔn)模板庫)是一套功能強(qiáng)大的?C++?模板類,提供了通用的模板類和函數(shù),這些模板類和函數(shù)可以實(shí)現(xiàn)多種流行和常用的算法和數(shù)據(jù)結(jié)構(gòu),如向量、鏈表、隊(duì)列、棧,今天我們來探究一下stl容器適配器的使用吧
    2023-01-01
  • 深入理解C++編程中的局部變量和全局變量

    深入理解C++編程中的局部變量和全局變量

    這篇文章主要介紹了深入理解C++編程中的局部變量和全局變量,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • Linux中使用VS Code編譯調(diào)試C++項(xiàng)目詳解

    Linux中使用VS Code編譯調(diào)試C++項(xiàng)目詳解

    最近因?yàn)轫?xiàng)目的需求,需要在Linux下開發(fā)C++相關(guān)項(xiàng)目,經(jīng)過一番摸索最終實(shí)現(xiàn)了,下面這篇文章就給大家簡單總結(jié)了一下如何通過VS Code進(jìn)行編譯調(diào)試的一些注意事項(xiàng)。有需要的朋友們可以參考借鑒,下面來跟著小編一起看看吧。
    2016-12-12
  • C/C++實(shí)現(xiàn)俄羅斯方塊游戲

    C/C++實(shí)現(xiàn)俄羅斯方塊游戲

    這篇文章主要介紹了如何利用C/C++實(shí)現(xiàn)經(jīng)典游戲之一的俄羅斯方塊,文中的實(shí)現(xiàn)步驟講解詳細(xì),對我們學(xué)習(xí)C語言和C++有一定的幫助,需要的可以參考一下
    2022-02-02
  • C++中輸出十六進(jìn)制形式的字符串

    C++中輸出十六進(jìn)制形式的字符串

    這篇文章主要給大家介紹了C++中輸出十六進(jìn)制形式的字符串,文中給出了詳細(xì)的介紹,有需要的朋友可以參考借鑒,下面來一起看看吧。
    2016-12-12
  • C++類和對象深入探索之分文件編寫點(diǎn)和圓的關(guān)系詳解

    C++類和對象深入探索之分文件編寫點(diǎn)和圓的關(guān)系詳解

    先前把C++類和對象的封裝講完了,并且留下了一個(gè)判斷兩個(gè)立方體是否相等的案例,但是那么多知識點(diǎn),僅僅一個(gè)案例是不夠的,所以再來一個(gè)分文件編寫點(diǎn)圓關(guān)系的案例;創(chuàng)建圓類和點(diǎn)類,圓類包含點(diǎn)類,算是一個(gè)嵌套吧,順便復(fù)習(xí)一下分文件編寫的方法,開整
    2022-05-05
  • OpenCV實(shí)現(xiàn)更改圖片顏色功能

    OpenCV實(shí)現(xiàn)更改圖片顏色功能

    這篇文章主要為大家詳細(xì)介紹了如何利用OpenCV實(shí)現(xiàn)更改圖片顏色的功能,文中代碼介紹詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C++運(yùn)算符重載的方法詳細(xì)解析

    C++運(yùn)算符重載的方法詳細(xì)解析

    運(yùn)算符重載的方法是定義一個(gè)重載運(yùn)算符的函數(shù),在需要執(zhí)行被重載的運(yùn)算符時(shí),系統(tǒng)就自動調(diào)用該函數(shù),以實(shí)現(xiàn)相應(yīng)的運(yùn)算。也就是說,運(yùn)算符重載是通過定義函數(shù)實(shí)現(xiàn)的
    2013-10-10
  • Qt采用線程以隊(duì)列方式實(shí)現(xiàn)下發(fā)數(shù)據(jù)

    Qt采用線程以隊(duì)列方式實(shí)現(xiàn)下發(fā)數(shù)據(jù)

    在C++中隊(duì)列是一種常用的數(shù)據(jù)結(jié)構(gòu)之一,一種特殊的線性表,一般采用先進(jìn)先出的方式。本文主要為大家介紹了Qt如何以隊(duì)列方式實(shí)現(xiàn)下發(fā)數(shù)據(jù),感興趣的可以了解一下
    2022-10-10
  • C++程序函數(shù)的重載和函數(shù)模板示例代碼

    C++程序函數(shù)的重載和函數(shù)模板示例代碼

    C++允許在同一作用域中用同一函數(shù)名定義多個(gè)函數(shù),這些函數(shù)的參數(shù)個(gè)數(shù)和參數(shù)類型不相同,這些同名的函數(shù)用來實(shí)現(xiàn)不同的功能,這就是函數(shù)的重載,這篇文章主要介紹了C++程序函數(shù)的重載和函數(shù)模板,需要的朋友可以參考下
    2024-03-03

最新評論