C++中的值初始化和默认初始化
1、值初始化
??????顧名思義,就是用數值初始化變量。如果沒有給定一個初始值,就會根據變量或類對象的類型提供一個初始值。對于int類型其值初始化后的值為0。
2、默認初始化:如果定義變量時沒有指定初值,則變量被默認初始化。其初始值和變量的類型以及變量定義的位置相關。默認初始化類對象和默認初始化內置類型變量有所不同。
對于默認初始化內置類型變量來說:
??????1)定義在函數體之外的變量是全局變量,一般存儲在全局區,存儲在全局區的變量一般會執行值初始化。此時,其初始值和變量的類型有關。對于int類型其初始值為0,對于char類型其默認初始值為' '。例子如下:
#include <iostream>
?
using namespace std;
?
int i;
double d;
char c;
?
int main()?
{
?? ?cout << "i = " << i << endl;
?? ?cout << "d = " << d << endl;
?? ?cout << "char" << c << "char" << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
?
??????2)定義在函數體內部的是局部變量,其存儲在棧區中,如果沒有指定初值,那么該局部變量將不會被初始化,也就是說這個局部變量的值是未定義的,是個隨機值。此時,如果不給這個局部變量賦值,那么就不能使用該局部變量,否則就會出錯,注意這種情況是沒有被初始化,既沒有使用默認初始化也沒有使用值初始化,沒有初始化的值是不能使用的。例子如下:
#include <iostream>
?
using namespace std;
?
int main()?
{
?? ?int i;
?? ?cout << "i = " << i << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
對于默認初始化類對象來說:不僅在創建類對象時,要使用默認構造函數,而且類成員要沒有類內初始值,類才會執行默認初始化。
??????如果是自定義的默認構造函數,不進行任何操作或者是編譯器合成的默認構造函數,其成員變量經過默認初始化之后的初始化值和局部變量的初始值是一樣的,即是隨機值,但是可以使用(類普通成員變量也存在棧區)。例子如下:
#include <iostream>
#include <string>
?
using namespace std;
?
class Init?
{
public:
?? ?int getA()?
?? ?{
?? ??? ?return a;
?? ?}
?? ?double getD()
?? ?{
?? ??? ?return d;
?? ?}
?? ?char getC()
?? ?{
?? ??? ?return c;
?? ?}
?? ?string getStr()
?? ?{
?? ??? ?return str;
?? ?}
?
private:
1、值初始化
??????顧名思義,就是用數值初始化變量。如果沒有給定一個初始值,就會根據變量或類對象的類型提供一個初始值。對于int類型其值初始化后的值為0。
2、默認初始化:如果定義變量時沒有指定初值,則變量被默認初始化。其初始值和變量的類型以及變量定義的位置相關。默認初始化類對象和默認初始化內置類型變量有所不同。
對于默認初始化內置類型變量來說:
??????1)定義在函數體之外的變量是全局變量,一般存儲在全局區,存儲在全局區的變量一般會執行值初始化。此時,其初始值和變量的類型有關。對于int類型其初始值為0,對于char類型其默認初始值為' '。例子如下:
#include <iostream>
?
using namespace std;
?
int i;
double d;
char c;
?
int main()?
{
?? ?cout << "i = " << i << endl;
?? ?cout << "d = " << d << endl;
?? ?cout << "char" << c << "char" << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
?
??????2)定義在函數體內部的是局部變量,其存儲在棧區中,如果沒有指定初值,那么該局部變量將不會被初始化,也就是說這個局部變量的值是未定義的,是個隨機值。此時,如果不給這個局部變量賦值,那么就不能使用該局部變量,否則就會出錯,注意這種情況是沒有被初始化,既沒有使用默認初始化也沒有使用值初始化,沒有初始化的值是不能使用的。例子如下:
#include <iostream>
?
using namespace std;
?
int main()?
{
?? ?int i;
?? ?cout << "i = " << i << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
對于默認初始化類對象來說:不僅在創建類對象時,要使用默認構造函數,而且類成員要沒有類內初始值,類才會執行默認初始化。
??????如果是自定義的默認構造函數,不進行任何操作或者是編譯器合成的默認構造函數,其成員變量經過默認初始化之后的初始化值和局部變量的初始值是一樣的,即是隨機值,但是可以使用(類普通成員變量也存在棧區)。例子如下:
#include <iostream>
#include <string>
?
using namespace std;
?
class Init?
{
public:
?? ?int getA()?
?? ?{
?? ??? ?return a;
?? ?}
?? ?double getD()
?? ?{
?? ??? ?return d;
?? ?}
?? ?char getC()
?? ?{
?? ??? ?return c;
?? ?}
?? ?string getStr()
?? ?{
?? ??? ?return str;
?? ?}
?
private:
?? ?int a;
?? ?char c;
?? ?double d;
?? ?string str;
};
?
int main()?
{
?? ?Init init;
?? ?
?? ?cout << "a = " << init.getA() << endl;
?? ?cout << "d = " << init.getD() << endl;
?? ?cout << "ccc" << init.getC() << "ccc" << endl;
?? ?cout << "str" << init.getStr() << "str" << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
對于string類型的成員變量是個空串,這可能和string類的內部實現有關。
3、默認初始化的出現場景。
?????1)當我們在塊作用域內不使用任何初始值定義一個非靜態變量或者數組時。數組和非靜態變量它們的值都是隨機值,但是數組可以使用,而非靜態變量需要在賦值以后才能使用。例子如下;
#include <iostream>
?
using namespace std;
?
int main()
{
?? ?int a[5];
?
?? ?for (int i = 0; i < 5; i++)
?? ?{
?? ??? ?cout << "數組元素值為:" << a[i] << endl;
?? ?}
?
1、值初始化
??????顧名思義,就是用數值初始化變量。如果沒有給定一個初始值,就會根據變量或類對象的類型提供一個初始值。對于int類型其值初始化后的值為0。
2、默認初始化:如果定義變量時沒有指定初值,則變量被默認初始化。其初始值和變量的類型以及變量定義的位置相關。默認初始化類對象和默認初始化內置類型變量有所不同。
對于默認初始化內置類型變量來說:
??????1)定義在函數體之外的變量是全局變量,一般存儲在全局區,存儲在全局區的變量一般會執行值初始化。此時,其初始值和變量的類型有關。對于int類型其初始值為0,對于char類型其默認初始值為' '。例子如下:
#include <iostream>
?
using namespace std;
?
int i;
double d;
char c;
?
int main()?
{
?? ?cout << "i = " << i << endl;
?? ?cout << "d = " << d << endl;
?? ?cout << "char" << c << "char" << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
?
??????2)定義在函數體內部的是局部變量,其存儲在棧區中,如果沒有指定初值,那么該局部變量將不會被初始化,也就是說這個局部變量的值是未定義的,是個隨機值。此時,如果不給這個局部變量賦值,那么就不能使用該局部變量,否則就會出錯,注意這種情況是沒有被初始化,既沒有使用默認初始化也沒有使用值初始化,沒有初始化的值是不能使用的。例子如下:
#include <iostream>
?
using namespace std;
?
int main()?
{
?? ?int i;
?? ?cout << "i = " << i << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
對于默認初始化類對象來說:不僅在創建類對象時,要使用默認構造函數,而且類成員要沒有類內初始值,類才會執行默認初始化。
??????如果是自定義的默認構造函數,不進行任何操作或者是編譯器合成的默認構造函數,其成員變量經過默認初始化之后的初始化值和局部變量的初始值是一樣的,即是隨機值,但是可以使用(類普通成員變量也存在棧區)。例子如下:
#include <iostream>
#include <string>
?
using namespace std;
?
class Init?
{
public:
?? ?int getA()?
?? ?{
?? ??? ?return a;
?? ?}
?? ?double getD()
?? ?{
?? ??? ?return d;
?? ?}
?? ?char getC()
?? ?{
?? ??? ?return c;
?? ?}
?? ?string getStr()
?? ?{
?? ??? ?return str;
?? ?}
?
private:
?? ?int a;
?? ?char c;
?? ?double d;
?? ?string str;
};
?
int main()?
{
?? ?Init init;
?? ?
?? ?cout << "a = " << init.getA() << endl;
?? ?cout << "d = " << init.getD() << endl;
?? ?cout << "ccc" << init.getC() << "ccc" << endl;
?? ?cout << "str" << init.getStr() << "str" << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
對于string類型的成員變量是個空串,這可能和string類的內部實現有關。
3、默認初始化的出現場景。
?????1)當我們在塊作用域內不使用任何初始值定義一個非靜態變量或者數組時。數組和非靜態變量它們的值都是隨機值,但是數組可以使用,而非靜態變量需要在賦值以后才能使用。例子如下;
#include <iostream>
?
using namespace std;
?
int main()
{
?? ?int a[5];
?
?? ?for (int i = 0; i < 5; i++)
?? ?{
?? ??? ?cout << "數組元素值為:" << a[i] << endl;
?? ?}
?
?? ?system("pause");
?? ?return 0;
}
在VS2015下編譯結果如下:
????2)當一個類本身含有類類型的成員且使用合成的默認構造函數時。使用合成的默認構造函數那么該類和其類類型成員都會執行默認初始化。
????3)當類類型的成員沒有在構造函數初始值列表中顯示地初始化時。說明該類類型成員會調用默認構造函數。
4、值初始化的出現場景
????1)在數組初始化的過程中如果我們提供的初始值數量少于數組的大小時,剩余的為提供初始值部分就會執行值初始化。
#include <iostream>
?
using namespace std;
?
int main()
{
?? ?int a[5] = {1, 2, 3};
?
?? ?for (int i = 0; i < 5; i++)
?? ?{
?? ??? ?cout << "數組元素值為:" << a[i] << endl;
?? ?}
?
?? ?system("pause");
?? ?return 0;
}
在VS2015下編譯結果如下:
由結果可知,沒有提供初始值的數組元素按照值初始化為了0。
????2)當我們不使用初始值定義一個局部靜態變量時。因為是靜態的,所以該局部靜態變量不再存儲在棧區,而是存儲在全局區。此時,就會根據類型進行設置該變量的初始值,即值初始化。例子如下:
#include <iostream>
?
using namespace std;
?
int main()
{
? ? static int a;
?? ?static char c;
?
?? ?cout << "a:" << a << endl;
?? ?cout << "ccc" << c << "ccc" << endl;?? ?
?
?? ?system("pause");
?? ?return 0;
}
VS2015編譯結果為:
????3)當我們通過書寫形如T()的表達式顯示請求值初始化時,其中T是類型名(vector的一個構造函數只接受一個實參用于說明vector的大小),它就是使用一個這種形式的實參來對它的元素初始器繼續值初始化)。
?
===》》》對于默認初始化,可以參考《C++ primer》P40頁
===》》》對于值初始化,可以參考《C++ primer》P88頁
===》》》對于默認初始化和值初始化的發生場景,可以參考《C++ primer》P262頁
===》》》對于合成的默認構造函數,可以參考《C++ primer》P235頁
點贊 4
————————————————
版權聲明:本文為CSDN博主「flychildc」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/J_H_C/article/details/83589282
?? ?system("pause");
?? ?return 0;
}
在VS2015下編譯結果如下:
????2)當一個類本身含有類類型的成員且使用合成的默認構造函數時。使用合成的默認構造函數那么該類和其類類型成員都會執行默認初始化。
????3)當類類型的成員沒有在構造函數初始值列表中顯示地初始化時。說明該類類型成員會調用默認構造函數。
4、值初始化的出現場景
????1)在數組初始化的過程中如果我們提供的初始值數量少于數組的大小時,剩余的為提供初始值部分就會執行值初始化。
#include <iostream>
?
using namespace std;
?
int main()
{
?? ?int a[5] = {1, 2, 3};
?
?? ?for (int i = 0; i < 5; i++)
?? ?{
?? ??? ?cout << "數組元素值為:" << a[i] << endl;
?? ?}
?
?? ?system("pause");
?? ?return 0;
}
在VS2015下編譯結果如下:
由結果可知,沒有提供初始值的數組元素按照值初始化為了0。
????2)當我們不使用初始值定義一個局部靜態變量時。因為是靜態的,所以該局部靜態變量不再存儲在棧區,而是存儲在全局區。此時,就會根據類型進行設置該變量的初始值,即值初始化。例子如下:
#include <iostream>
?
using namespace std;
?
int main()
{
? ? static int a;
?? ?static char c;
?
?? ?cout << "a:" << a << endl;
?? ?cout << "ccc" << c << "ccc" << endl;?? ?
?
?? ?system("pause");
?? ?return 0;
}
VS2015編譯結果為:
????3)當我們通過書寫形如T()的表達式顯示請求值初始化時,其中T是類型名(vector的一個構造函數只接受一個實參用于說明vector的大小),它就是使用一個這種形式的實參來對它的元素初始器繼續值初始化)。
?
===》》》對于默認初始化,可以參考《C++ primer》P40頁
===》》》對于值初始化,可以參考《C++ primer》P88頁
===》》》對于默認初始化和值初始化的發生場景,可以參考《C++ primer》P262頁
===》》》對于合成的默認構造函數,可以參考《C++ primer》P235頁
點贊 4
————————————————
版權聲明:本文為CSDN博主「flychildc」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/J_H_C/article/details/83589282
?? ?int a;
?? ?char c;
?? ?double d;
?? ?string str;
};
?
int main()?
{
?? ?Init init;
?? ?
?? ?cout << "a = " << init.getA() << endl;
?? ?cout << "d = " << init.getD() << endl;
?? ?cout << "ccc" << init.getC() << "ccc" << endl;
?? ?cout << "str" << init.getStr() << "str" << endl;
?
?? ?system("pause");
?? ?return 0;
}
在VS2015中編譯結果如下:
對于string類型的成員變量是個空串,這可能和string類的內部實現有關。
3、默認初始化的出現場景。
?????1)當我們在塊作用域內不使用任何初始值定義一個非靜態變量或者數組時。數組和非靜態變量它們的值都是隨機值,但是數組可以使用,而非靜態變量需要在賦值以后才能使用。例子如下;
#include <iostream>
?
using namespace std;
?
int main()
{
?? ?int a[5];
?
?? ?for (int i = 0; i < 5; i++)
?? ?{
?? ??? ?cout << "數組元素值為:" << a[i] << endl;
?? ?}
?
?? ?system("pause");
?? ?return 0;
}
在VS2015下編譯結果如下:
????2)當一個類本身含有類類型的成員且使用合成的默認構造函數時。使用合成的默認構造函數那么該類和其類類型成員都會執行默認初始化。
????3)當類類型的成員沒有在構造函數初始值列表中顯示地初始化時。說明該類類型成員會調用默認構造函數。
4、值初始化的出現場景
????1)在數組初始化的過程中如果我們提供的初始值數量少于數組的大小時,剩余的為提供初始值部分就會執行值初始化。
#include <iostream>
?
using namespace std;
?
int main()
{
?? ?int a[5] = {1, 2, 3};
?
?? ?for (int i = 0; i < 5; i++)
?? ?{
?? ??? ?cout << "數組元素值為:" << a[i] << endl;
?? ?}
?
?? ?system("pause");
?? ?return 0;
}
在VS2015下編譯結果如下:
由結果可知,沒有提供初始值的數組元素按照值初始化為了0。
????2)當我們不使用初始值定義一個局部靜態變量時。因為是靜態的,所以該局部靜態變量不再存儲在棧區,而是存儲在全局區。此時,就會根據類型進行設置該變量的初始值,即值初始化。例子如下:
#include <iostream>
?
using namespace std;
?
int main()
{
? ? static int a;
?? ?static char c;
?
?? ?cout << "a:" << a << endl;
?? ?cout << "ccc" << c << "ccc" << endl;?? ?
?
?? ?system("pause");
?? ?return 0;
}
VS2015編譯結果為:
????3)當我們通過書寫形如T()的表達式顯示請求值初始化時,其中T是類型名(vector的一個構造函數只接受一個實參用于說明vector的大小),它就是使用一個這種形式的實參來對它的元素初始器繼續值初始化)。
?
===》》》對于默認初始化,可以參考《C++ primer》P40頁
===》》》對于值初始化,可以參考《C++ primer》P88頁
===》》》對于默認初始化和值初始化的發生場景,可以參考《C++ primer》P262頁
===》》》對于合成的默認構造函數,可以參考《C++ primer》P235頁
點贊 4
————————————————
版權聲明:本文為CSDN博主「flychildc」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/J_H_C/article/details/83589282
總結
以上是生活随笔為你收集整理的C++中的值初始化和默认初始化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++构造函数之委托构造函数
- 下一篇: 为什么是错的?????