C++入門教程(20):變量、不變量和常量

小古銀的官方網站(完整教程):http://www.xiaoguyin.com/
C++入門教程視頻:https://www.bilibili.com/vide...ios


變量

前面簡單講解過變量,如今就再詳細講解變量。ide

先給出幾個關於變量的建議函數

  • 基本數據類型的變量要初始化。
  • 避免使用全局變量。
  • 每一個變量聲明時單獨一行。
  • 變量名稱應該符合變量的用途。

基礎示例

#include <iostream> // std::cout std::endl
#include <string> // std::string

std::string global = "這是全局變量"; // 全局變量, 做用域是全局, 即在程序結束是纔會銷燬

int main(int argc, char *argv[]) // 函數參數也是變量, 做用域是該函數內部, 即函數之外就不存在
{
    std::string text1 = "這是局部變量"; // 局部變量, 做用域是最近的左右大括號, 即做用域是主函數

    // 在代碼中加入左右大括號能夠限制變量的做用域
    {
        std::string text2 = "這也是局部變量"; // 做用域是最近的左右大括號, 即下一行之後它佔用的內存就會被銷燬而不存在
        std::cout << text1 << std::endl << text2 << std::endl;
    }
    std::cout << text1 << std::endl;
    std::cout << global << std::endl;
    std::cout << argc << std::endl;

    // 這個輸出的是內存中的地址
    // 因爲每次程序啓動都是由系統從新分配內存
    // 因此每次輸出的內存地址都不會同樣
    std::cout << argv << std::endl;

    return 0;
}

輸出結果:網站

這是局部變量
這也是局部變量
這是局部變量
這是全局變量
1
034D6538

基礎講解

前面教程提到過std::string聲明的變量用來保存字符串,如:code

std::string text = "這是字符串";

聲明變量的位置大體分爲三種:視頻

  • 全局變量:在全部函數以外聲明的變量。它的做用域是全局,整個程序全部地方均可以使用這個變量,程序結束時才釋放變量的內存。
  • 局部變量:除全局變量之外的都是局部變量。它的做用域是離它最近的一對左右大括號{ }之間,在程序執行到},那麼,這個變量的內存就會釋放,換言之,在它的做用域之外的地方,這個變量是不存在的。
  • 形式參數:形式參數是特殊的局部變量,它在函數名後面的一對圓括號中定義。它的做用域就在這個函數內,在這個函數之外的地方,這個變量不存在。代碼中的argc和argv就是形式參數。

基礎拓展

注意教程

  1. 若是兩個不一樣做用域有着兩個變量,而這兩個變量名稱是同樣的,那麼它們並非同一個變量。
  2. 若是在一個做用域中有一個子做用域,子做用域與外部做用域都含有相同名字的變量(如全局變量和局部變量),那麼,在子做用域使用的變量是子做用域的變量。

建議變量初始化的緣由:基本數據類型的變量聲明以後,它會保存一個不肯定的數,爲了防止程序使用這個不肯定的數致使程序出現問題(其餘數據類型則要看狀況,如std::string則不須要初始化)。內存

避免使用全局變量的緣由:上面注意中的第二條就是緣由,防止寫程序時誤操做。若是爲局部變量起一個名字與全局變量,當全局變量多了,開發過程當中就會思考局部變量起名字的問題,會致使開發變慢和代碼難讀的問題。作用域

爲注意中的兩點舉一個例子:開發

#include <iostream> // std::cout std::endl
#include <string> // std::string

std::string global = "這是全局變量";

int main(void)
{
    std::string global = "這個global並非全局變量";
    std::cout << global << std::endl;

    {
        std::string text = "局部變量1";
        std::cout << text << std::endl;
    }

    {
        std::string text = "局部變量2";
        std::cout << text << std::endl;
    }
    return 0;
}

輸出結果:

這個global並非全局變量
局部變量1
局部變量2

在編譯的過程當中,應該會看到一個警告,說是局部變量隱藏了全局變量。那麼這個全局變量global在局部變量global的做用域(即主函數)裏都是不能使用的。這就是新手要注意的:不能忽視警告信息

const

既然有變量,那麼相對應的就應該有不變量。

有一些變量,初始化以後就並不想它再改變,那麼它就是不變量。然而,實際上這個變量保存的值仍是能夠改變。爲了防止之後不當心給這些不想被改變的變量賦值,因此出現了關鍵字const

const就是爲了禁止變量保存的值改變而出現的。用const聲明的變量,當試圖改變這個變量的值,那麼出現編譯錯誤。因此const聲明的變量就是不變量。

因爲const聲明的變量,後面不能被改變,因此const聲明的變量必須被初始化

基礎示例

#include <iostream> // std::cout std::endl

int main(void)
{
    const int a = 100; // 不變量a, 若是去掉賦值, 編譯就會報錯, 提示必須初始化
    std::cout << a << std::endl;

    // 若是去掉下面的註釋, 那麼編譯的時候會報錯, 說a是不能修改的
    // a = 2333;

    return 0;
}

輸出結果:

100

基礎講解

因爲變量a聲明的時候使用了const,因此下面它保存的值都不能發生變化。

建議:每一個const變量聲明時單獨一行。

注意const變量的注意事項跟變量的注意事項相同。

基礎拓展

像數字123、字符'a'等這些字面量,它們是不變的值,因此它們是常量

上面代碼中因爲變量a保存的是字面量,並且保存的值不會改變,因此變量a也是常量。

constexpr

關鍵字constexpr是更嚴格的constconst做用是不改變變量,而constexpr變量保存的值必須能夠在編譯的時候求出來。這意味着constexpr變量必須保存字面量:

int a = 1;
constexpr int b = 2;
constexpr int c = b;
// 去掉下一行代碼將會報錯
// constexpr int d = a;

因爲變量a的值在程序中可變,並不能在編譯期肯定,因此constexpr int d = a;將會報錯。而constexpr int b = 2;,2是字面量,那麼constexpr聲明的變量b就能夠在編譯期肯定它的值,就是2,而且不會被改變。因爲變量bconstexpr,因此constexpr int c = b;也是成立的;編譯器在編譯期會轉化成constexpr int c = 2;

初始值

咱們知道,變量聲明時就應該初始化,接下來,來看看比較有意思的初始值。

基本數據類型初始化時,除了指定明確的數值之外,還可使用默認初始值:

基礎示例

#include <iostream>

int main(void)
{
    int a = int();
    float b = float();
    unsigned long long c = unsigned long long();
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << c << std::endl;
    return 0;
}

輸出結果:

0
0
0

基礎講解

從代碼中能夠看出,基本數據類型的默認初始值就是基本數據類型後面加上(),如int()。而默認初始值的實際數值就是0

固然,你也能夠在括號內寫數值,如int a = int(5);,那麼就等價於int a = 5;

補充知識(瞭解便可)

關鍵字constexpr是從C++11起加入。

相關文章
相關標籤/搜索