變數和基本型別

2021-05-27 07:30:20 字數 3884 閱讀 5818

算術型別(arithmetic type)

c++標準規定了每個算術型別的最小儲存空間,但允許編譯器使用更大的儲存空間。事實上,對於int型,幾乎現在所有的編譯器使用的儲存空間都比所要求的大(也表明,在編寫程式時不能對這些型別的大小做任何假設)。c++算術型別最小儲存空間規定如下:

(注:要特別注意int型,並且這裡沒有long long型別,基本上所有編譯器都有這個擴充套件)

型別含義

最小儲存空間

bool

布林型-

char

字元型8位

wchar_t

寬字元型 

16位 

short

短整型16位 

int整形型

16位long

長整型 

32位float

單精度浮點型

6位有效數字

double

雙精度浮點型 

10位有效數字

long double

擴充套件精度浮點型

10位有效數字

signed與unsigned型別

c++標準並沒有定義signed型別如何用位來表示,編譯器通常用其中一位作為符號位來表示。

對於unsigned 整型(unsigned char,unsigned short int, unsigned int, unsigned long int),編譯器會將越界值對2^n取模(n為該型別的位數)使其滿足大小要求。因此,unsigned整型在計算時不會發生溢位。

例如:(假設char型別為8位,2^8 = 256)

unsigned char ch = 300; 等價於 unsigned char ch = 44 (300 mod 256)

unsigned char ch = -1;  等價於 unsigned char ch = 255 (-1 mod 256)

而對於越界的signed型別賦值的情形,標準沒有明確說明,也就是未定義行為。很多編譯器採用與unsigned型別一樣的處理方式。

字面值(literal, or literal constant)

只有內建型別存在字面值,每個字面值都有相應的型別。例如:0是int型,2.718是double型。

整形字面值

整型字面值的型別依賴於它的形式、值和型別字尾:

如果乙個字面值不能夠被它所有可能型別所表示,那麼將產生未定義行為。

字串字面值(string literal)

形如"..."或者l"..."的字串。

不是以l開頭的字串字面值,叫作平凡字串字面值(ordinary string literal),也叫作窄字串字面值(narrow string literal)。對於平凡字串字面值,其型別是const char[num],靜態儲存區,並用所給字串初始化。

以l開頭的字串字面值,例如:l"foo",是寬字串字面值。它的型別是const wchar_t[num],靜態儲存區,並用所給字串初始化。

(注意上面的num值為所給字串中字元個數 + 1)

所有字串字面值的儲存是否是不重疊的,這個問題是由實現定義的(implementation-defined)。試圖去修改字串字面值的行為所產生的結果是未定義的。

在編譯時,相鄰的窄字串字面值被連線成乙個窄字串字面值,相鄰的寬字串字面值也被連線成乙個寬字串字面值。如果乙個窄字串字面值和乙個寬字串字面值相鄰,其結果是未定義了。

變數及其型別

c++沒有規定變數名的長度。

一些特殊的識別符號為實現專用的保留識別符號:

1)包含兩個連續下劃線的識別符號以及以下劃線開頭緊跟乙個大寫字母的識別符號。

2)在函式外定義的以下劃線開頭的識別符號。

初始化初始化有兩種方式:

1)拷貝初始化(copy-initialization),例如:int var = 6;

2)直接初始化(direct-initialization),例如:int var(6);

兩種方式對於內建型別是沒區別的,而對於類型別是有區別的,詳見建構函式章節。

extern與const

如果extern宣告有初始化表示式,那麼它被認為是定義,而忽略extern。例如:

extern

int var = 6;

//definition (只有當extern 宣告位於函式外部時,才可以含有初始化表示式)

const限定符

在全域性作用域內宣告的const變數為內部連線屬性,即是檔案域變數,所以可以把const變數定義放在標頭檔案中(如果這樣做,那麼在每個包含該標頭檔案中的檔案中都會有乙個該變數的定義,這樣可能造成儲存空間的大量浪費。事實上,當const變數是用常量表示式初始化時,大部分編譯器在編譯時都會用相應的常量表示式替換這些const變數的任何使用。也就不會有空間用於這類const變數的儲存)。

可以指定const變數為extern,從而使其變成外部連線屬性,可以在整個程式中訪問const物件(需要在定義和使用處都用extern宣告)。如果定義了乙個extern const變數,那麼在其它檔案中就不能再在全域性域定義該變數(乙個例外是,可以定義乙個內部連線屬性的const變數)。例如:

// file1.cpp

extern

const

int var = 6;

// file2.cpp

extern

const

int var;

//legal: refer to the var in file1

// file3.cpp

const

int var = 9;

//legal: internal linkage, only used in this file

// file4.cpp

extern

const

int var = 2;

//illegal: redefinion of var (already defined in file1)

// file5.cpp

int var;

//illegal: redefinion of var (already defined in file1)

int var = 6;

//int& r = 9;             // error!

const

int& r1 = 9;

// ok

const

int& r2 = var + r1;

// ok

為什麼const引用則可以繫結到不同但相關的型別的物件、甚至繫結到右值呢?

因為如果是繫結到不同型別的物件或右值,會先生成乙個與引用型別相同的臨時物件(必要時進行型別轉換),然後引用變數再與該臨時物件繫結。由於臨時物件是右值,所以只能進行const引用。

另外,還可以從另乙個角度來解釋,先看下面的例子:

double var = 2.718;

const

int& r = var;

上面的**等價於:

double var = 2.718;

int tmp = var;

const

int& r = tmp;

如果r不是const引用,那麼可以修改r的值。這樣做,事實上是修改了臨時變數tmp的值,而與程式設計師試圖修改var的值的意願完全偏離。這種錯誤是很難察覺的。而const引用不能修改,就完全避免了這種錯誤的發生。

列舉型別

列舉型別的物件的初始化或賦值只能通過其列舉成員或同一列舉型別物件進行。
當需要整形常量時,用列舉型別(匿名列舉型別)代替#define預處理命令是乙個不錯的選擇。

變數和基本型別

c 程式通常由許多檔案組成,為了讓多個檔案訪問相同的變數,c 區分了宣告和定義。變數的定義 definition 用於為變數分配儲存空間,還可以為變數指定初始值。在乙個程式中,變數有且僅有乙個定義。c 支援兩種初始化變數的形式 複製初始化 copy initialization 和直接初始化 dir...

變數和基本型別

一 資料型別 c 主要有bool,char,short,int,long,long long float,double,long double,wchar t 寬字元 char16 t char32 t unicode字元 每個型別對應不同的位元組尺寸,以上型別都是有符號的,加上關鍵字unsigne...

變數和基本型別

1.變數宣告和定義的關係extern int j 宣告j int j 定義j extern int j 0 定義2.識別符號的組成 3.變數命名規範 4.作用域理解 include 該程式僅用於說明,函式內部不宜定義與全域性變數同名的變數 int i 0 全域性變數 intmain 5.引用 引用並...