學習c++已經很久了,由於工作原因,很長一段時間沒有用了,再加上經常用一些指令碼語言,使得對c++的一些概念,反而有些混亂。所以這裡我跟大家一起討論一下c++的型別轉換。如文章中有任何紕漏,還請指正。
眾所周知,在python和其他一些指令碼語言中,宣告變數是不需要指定型別的。
a=5
b="hello"
但是在c++中這樣宣告變數,顯然是不能通過編譯的。需要指定變數的型別:
int a=5;
char b="hello"
如果經常用指令碼語言你想要a+b
那麼在python中你直接這樣就行了
c=chr(a)+b
print(c)
直譯器會自動根據你指定的型別轉換函式 ,直接操作並得出結果,下面是python中的一些型別轉換函式:
[python]
int(x [,base ]) 將x轉換為乙個整數
long(x [,base ]) 將x轉換為乙個長整數
float(x ) 將x轉換到乙個浮點數
complex(real [,imag ]) 建立乙個複數
str(x ) 將物件 x 轉換為字串
repr(x ) 將物件 x 轉換為表示式字串
eval(str ) 用來計算在字串中的有效python表示式,並返回乙個物件
tuple(s ) 將序列 s 轉換為乙個元組
list(s ) 將序列 s 轉換為乙個列表
chr(x ) 將乙個整數轉換為乙個字元
unichr(x ) 將乙個整數轉換為unicode字元
ord(x ) 將乙個字元轉換為它的整數值
hex(x ) 將乙個整數轉換為乙個十六進製制字串
oct(x ) 將乙個整數轉換為乙個八進位制字串
我們這裡主要討論 c++的型別轉換。如果想要讓上面c++中宣告的兩個變數相加。那麼我們也會用到型別轉換函式:
int a = 5;
char b = "hello";
char c[10];
_itoa_s(a, c, 10);
strcat_s(c, b);
printf("%s", c);
這樣看來是相當的複雜了。所以我們還是有必要學習一下c++的型別轉換。也是為了方便以後的應用。我們在實際應用中一般很少對物件直接進行型別轉換。而且這樣也經常是不合法的。
例如
struct m ;
struct r ;
void printm(r* c)
int main(int argc, char* argv)
編譯器會提示不存在使用者定義的型別轉換。那麼我們怎麼才能讓程式順利的執行呢。只能用一些型別轉換的技巧。
struct m ;
struct r ;
void printm(r* c)
int main(int argc, char* argv)
這樣就可以順利的編譯通過,雖然列印的值跟自己想要的結果大相徑庭。我們這裡用到乙個概念就是 void lpvoid的指標。通過轉換指標型別,來強制滿足編譯器對型別的要求。我們之所以這樣做,還是因為c++中的各種資料型別所佔的記憶體空間是不一樣的。
16位編譯器
char :1個位元組
char*(即指標變數): 2個位元組
short int : 2個位元組
int: 2個位元組
unsigned int : 2個位元組
float: 4個位元組
double: 8個位元組
long: 4個位元組
long long: 8個位元組
unsigned long: 4個位元組
32位編譯器
char :1個位元組
char*(即指標變數): 4個位元組(32位的定址空間是2^32, 即32個bit,也就是4個位元組。同理64位編譯器)
short int : 2個位元組
int: 4個位元組
unsigned int : 4個位元組
float: 4個位元組
double: 8個位元組
long: 4個位元組
long long: 8個位元組
unsigned long: 4個位元組
64位編譯器
char :1個位元組
char*(即指標變數): 8個位元組
short int : 2個位元組
int: 4個位元組
unsigned int : 4個位元組
float: 4個位元組
double: 8個位元組
long: 8個位元組
long long: 8個位元組
unsigned long: 8個位元組
正是因為如此,所以我們想要直接轉換資料型別是行不通的。只能通過一些技巧才能進行轉換。尤其是在使用者自定義的資料型別中。特別重要。很多時候我們會被各種各樣的型別轉換弄得暈頭轉向。下面這段**說明了為什麼指標之間的型別轉換會被編譯器所接受。
struct m ;
int main(int argc, char* argv)
用好c++的關鍵除了oop之外,就是我們能夠正確的把乙個資料型別傳遞給函式。有時候我們編寫了自己的類/結構體。但是需要傳遞的函式引數的型別卻與我們的大相徑庭。如何才能把自己的資料結構正確的傳遞給函式的引數。決定了我們對c++資料型別的掌握程度。有些時候我們的轉換雖然通過了編譯器,但是卻隱藏了致命的錯誤,使得程式在發布之後出現各種bug,因此我覺得這個型別轉換真的需要好好的學習,理解。
當然我們還需要知道c++中的4種強制型別轉換。
1、static_cast
用法:static_cast (expression)
該運算子把expression轉換為type-id型別,但沒有執行時型別檢查來保證轉換的安全性。它主要有如下幾種用法:
(1)用於類層次結構中基類和派生類之間指標或引用的轉換
進行上行轉換(把派生類的指標或引用轉換成基類表示)是安全的
進行下行轉換(把基類的指標或引用轉換為派生類表示),由於沒有動態型別檢查,所以是不安全的
(2)用於基本資料型別之間的轉換,如把int轉換成char。這種轉換的安全也要開發人員來保證
(3)把空指標轉換成目標型別的空指標
(4)把任何型別的表示式轉換為void型別
注意:static_cast不能轉換掉expression的const、volitale或者__unaligned屬性。
2、dynamic_cast
用法:dynamic_cast (expression)
該運算子把expression轉換成type_id型別的物件。type_id必須是類的指標、引用或者void*;
如果type_id是類指標型別,那麼expression也必須是乙個指標,如果type_id是乙個引用,那麼expression也必須是乙個引用。
dynamic_cast主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。
在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;
3、reinterpret_cast
用法:rei
nterpret_cast (expression)
type-id必須是乙個指標、引用、算術型別、函式指標或者成員指標。
它可以把乙個指標轉換成乙個整數,也可以把乙個整數轉換成乙個指標(先把乙個指標轉換成乙個整數,
在把該整數轉換成原型別的指標,還可以得到原先的指標值)。
該運算子的用法比較多。
(static_cast .與. reinterpret_cast比較,見下面 )
該運算子平台移植性比價差。
4、const_cast
用法:const_cast (expression)
該運算子用來修改型別的const或volatile屬性。除了const 或volatile修飾之外, type_id和expression的型別是一樣的。
常量指標被轉化成非常量指標,並且仍然指向原來的物件;
常量引用被轉換成非常量引用,並且仍然指向原來的物件;常量物件被轉換成非常量物件。
為什麼都說c++是乙個複雜的語言,我覺得不是他的oop特性,而是這些基於底層的細節導致的。在敏捷型語言快速發展遍地開花的今天。我們要想把c++學好,只能通過不斷的反覆學習,總結經驗才能掌握好它的本質。
mysql型別轉換c 型別轉換 C 型別轉換
一 簡介 型別轉換 把資料從一種型別轉換另一種型別 我們要求等號兩邊參與運算子必須型別一致,如果不一致,滿足下列條件會發生自動型別轉換或者隱式型別轉換。1.兩種型別相容 例如 int和double 相容 都是數字型別 2.目標型別大於源型別 double int 顯示型別轉換 1.兩種型別相相容 i...
C 的型別轉換
2008 03 15 12 59 強制型別轉換容易引發錯誤,所以被認為是一種醜陋的語法。c 中有乙個觀念 醜陋的語法就應該用醜陋的方式表達。所以,c 的轉換操作符使用 x cast 這種一種繁瑣的形式。目的是為了讓你在使用型別轉換前三思而行,看看是不是又不需要型別轉換的方法或設計。更重要的是,c風格...
C 型別的轉換
型別的轉換c 中型別轉換 顯隱 的機制分為兩種 一 隱式轉換 implicit conversions 二 顯式轉換 explict conversions 隱式轉換不需要指明欲轉變的型別 顯式轉換明確地使用轉換運算子 cast 指定要轉換成哪一種型別。c 允許程式設計師如果對於溢位進行處理 che...