天天看點

C++ 變量、常量、符号常量

變量:

int i = 0;  // i 是變量

i=5;         //i 可以修改

 變量就是程式内一個記憶體位置的符号名,在該記憶體位置可以儲存資料,并可以通過符号名對該記憶體位址存放的資料進行通路。

變量的值可以修改,是可變的,但在某個确定的時刻,變量的值是确定的,并一直保持到下次被修改之前。 

常量:

int a=10;       //a 是變量, 10 是常量,也是整形常量

double  b= 3.5;  //b是變量, 3.5 這個數是常量,也叫浮點型常量

char c= 'A' ;  //c是變量,  ‘A’ 是字元常量

std::string  str ="1234";   // str 是變量, “1234”是字元串常量

上面這四種常量都叫做普通常量,也稱之為字面值常量。

字面值常量在程式中是直接表示的,整型直接寫出大小,字元直接寫出字元 ,如上面的10 和 ‘A ’ 

一個字面值常量在編譯時被直接解析為立即數,編譯器内部維護字面值常量的類型,

以前一直以為const修飾的變量是常量,既對,也錯,應該稱為  符号常量

const int   i = 10 ; // i 是const 修飾的,i本身是變量, 但是被const 修飾後變成了符号常量,不可修改

//當然,10 還是常量,也是字面值常量 ,而 i  是符号常量,和普通常量不一樣的是,符号常量有一個名稱,既i , 而普通常量也就是字面值常量是沒有名稱的

符号常量的定義的兩種方式:#define  和const 

#define A 10  

const int B=10;

不同之處在于: 

a. 宏定義: 由預處理處理,單純的是純文字替換。 

b. const常量: 由C++編譯器處理,提供類型檢查和作用域檢查。

ps:建議把常量定義為大寫形式

常量存儲在什麼地方:

一個由C/C++編譯的程式占用的記憶體分為以下幾個部分 

1、棧區(stack)— 由編譯器自動配置設定釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于資料結構中的棧。 

2、堆區(heap) — 一般由程式員配置設定釋放, 若程式員不釋放,程式結束時可能由OS回收 

3、全局(靜态)區(static):

全局變量和靜态變量的存儲是放在一塊的,初始化的全局變量和靜态變量在一塊區域, 未初始化的全局變量和未初始化的靜态變量在相鄰的另一塊區域。 - 程式結束後有系統釋放 

4、文字常量區 —常量字元串就是放在這裡的。 程式結束後由系統釋放 

5、程式代碼區—存放函數體的二進制代碼。

例子程式: 

//main.cpp:

#include<iostream>

using namespace std;

int a = 0;                                 全局(靜态)初始化區 

char *p1;                                 全局(靜态)未初始化區 

int  main() 

    int b=10;                             b在棧 ,10呢?10沒有存在任何地方,編譯器在指令中直接把10作為立即數指派給了b

    char *p2;                            棧 

    char *p3 = "123456";         "123456"在常量區,p3在棧上。 

    p1 = (char *)malloc(10);     配置設定得來10位元組的區域在堆區

    strcpy(p1, "123456");         "123456"放在常量區,編譯器可能會将它與p3所指向的"123456"優化成一個地方

}

重點有兩個:

1.為什麼  int b=10;   10這個常量 沒有放在文字常量區,不是說常量都放在這裡嗎?

這是因為編譯器認為普通的整型、浮點型或字元型常量在使用的時候是可以通過立即數來實作的,沒有必要額外存儲到資料區,如此節省了存儲空間和運作時的通路時間

2.那麼什麼樣的資料才将放入常量區呢?

第一就是”12345“ 這樣的字元串常量,但是要除掉字元數組指派的常量

第二就是被const修飾的全局變量

除了字元串之外,其他常量也可以放在常量區,但是前提是該資料必須被存放在全局變量的空間裡,并且被const關鍵字修飾。如下:

#include<iostream>
using namespace std;

const int v0=5;        //5這個常量在常量區,因為是全局const, v0在全局(靜态)初始化區 
const char c='t';      //'t'這個常量在常量區,因為是全局const, c在全局(靜态)初始化區 
int v1=6;              //6這個常量是立即數,沒有存在任何地方 ,v1在全局(靜态)初始化區 

int main()
{
    const int x=0;        //'0'這個常量也是立即數,因為不是全局的,x則在棧中
    double x=10;          //'10'這個常量也是立即數,x則在棧中
    string str="12345";   //"12345"在常量區,str在棧中
    char a[]="123";       //特殊,"123"也相當于立即數,沒有村拽任何地方,a在棧中,儲存了123
    return 0;
}
           

至于為什麼?要好好學習彙編,看看編譯器到底做了什麼?

參考:http://emb.hqyj.com/Column/Column540.htm