日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C/C++中的数据类型转换

發布時間:2025/4/5 c/c++ 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C/C++中的数据类型转换 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 隱式類型轉換
      • 1.1 隱式類型轉換的基本概念
      • 1.2 隱式類型轉換的發生點
      • 1.3 浮點數賦值給整形數分析
    • 2 C語言中的強制類型轉換
    • 3 C++中的強制類型轉換
      • 3.1 static_cast
      • 3.2 const_cast
      • 3.3 reinterpret_cast
      • 3.4 dynamic_cast
      • 3.5 類型轉換使用建議

C/C++語言中的數據類型轉換主要有兩種:強制類型轉換和隱式類型轉換。

1 隱式類型轉換

1.1 隱式類型轉換的基本概念

我們首先需要知道,隱式類型轉換是編譯器主動進行的類型轉換。

對于隱式數據類型轉換來說:

  • 低類型到高類型的隱式類型轉換是安全的,不會產生截斷。
  • 高類型到低類型的隱式類型轉換是不安全的,導致不正確的結果。
  • 比如:浮點數賦值給整形時,會發生截斷(小數部分丟失)。

注意: 標準C編譯器的類型檢查是比較寬松的,因此隱式類型轉換可能帶來意外的錯誤。

1.2 隱式類型轉換的發生點

隱式類型轉換的發生點如下:

  • 算術運算式中,低類型轉換為高類型。
  • 賦值表達式中,表達式的值轉換為左邊變量的類型。
  • 函數調用時,實參轉換為形參的類型。
  • 函數返回值,return表達式轉換為返回值類型。

安全的隱式類型轉換:

1.3 浮點數賦值給整形數分析

直接賦值:

可以看到,編譯器直接將浮點數截斷。

通過函數調用:


可以看到,函數調用時也是發生了隱式類型轉換,編譯器直接將浮點數進行截斷。

注意:當使用如下語句時printf("%d\n", 3.14);,將得到錯誤的結果。由于是變參,所以編譯器根本不知道是什么類型,不會進行隱式類型轉換。


2 C語言中的強制類型轉換

強制類型轉換的語法:

  • (Type)var_name;
  • (Type)value;

強制類型轉換的結果:

  • 目標類型能夠容納目標值,結果不變。
  • 目標類型不能容納目標值:結果將產生截斷。
  • 注意:不是所有的強制類型轉換都能成功,當不能進行強制類型轉換時,編譯器將產生錯誤信息。

3 C++中的強制類型轉換

C 方式強制類型轉換存在的問題:

  • 過于粗暴:任意類型之間都可以進行轉換,編譯器很難判斷其正確性。
  • 難于定位 :在源碼中無法快速定位所有使用強制類型轉換的語句。

問題:強制類型轉換在實際工程中是很難完全避免的!如何進行更加安全可靠的轉換?

C++ 將強制類型轉換分為4種不同的類型: static_cast、const_cast、dynamic_cast、reinterpret_cast。

用法:xxx_cast(Expression)

3.1 static_cast

static_cast強制類型轉換:

  • 用于類層次結構中基類(父類)和派生類(子類)之間指針或引用的轉換。上行指針或引用(派生類到基類)轉換安全,下行不安全。
  • 用于基本數據類型之間的轉換,如把int轉換成char,把int轉換成enum。這種轉換的安全性也要開發人員來保證。
  • 把空指針轉換成目標類型的空指針。
  • 把任何類型的表達式轉換成void指針類型。
#include <iostream>using namespace std;class Animal { public:virtual void cry() = 0; };class Cat :public Animal { public:void cry(){cout << "喵喵瞄" << endl;}};class Dog :public Animal { public:void cry(){cout << "汪汪汪" << endl;}};int main(void) {//第一種情況 父子類之間的類型轉換Dog* dog1 = new Dog();Animal* a1 = static_cast<Animal*>(dog1); //子類的指針轉型到父類指針Dog* dog1_1 = static_cast<Dog*>(a1); //父類的指針轉型到子類的指針Cat* cat1 = static_cast<Cat*>(a1); //父子到子類,有風險,這樣時不行的,會出問題,但是我們如果去調用cat1相關的函數時,不管是不是虛函數都是Cat類的函數,這就是靜態連編。如果兩者之間的內存結構不同,則可能會出錯。Dog dog2;Animal& a2 = static_cast<Animal&>(dog2); //子類的引用轉型到父類的引用Dog &dog2_2 = static_cast<Dog&>(a2); //父類到子類引用//第二種 基本類型的轉換int kk = 234;char cc = static_cast<char>(kk);//第三種 把空指針轉換成目標類型的空指針。int* p = static_cast<int*>(NULL);Dog* dp = static_cast<Dog*>(NULL);//第四種 把任何類型的表達式轉換成void類型int* pi = new int[10];void* vp = static_cast<void*>(pi);vp = pi;system("pause");return 0; }

3.2 const_cast

const_cast強制類型轉換:

  • 用于去除變量的只讀屬性。
  • 強制轉換的目標類型必須是指針或引用。
void const_cast_demo() {const int& j = 1;int& k = const_cast<int&>(j);const int x = 2; //真正意義上的常量int& y = const_cast<int&>(x);//編譯器會為x分配空間,y指向的是為x分配的空間int z = const_cast<int>(x); //errork = 5;printf("k = %d\n", k);printf("j = %d\n", j);y = 8;printf("x = %d\n", x);printf("y = %d\n", y);printf("&x = %p\n", &x);printf("&y = %p\n", &y); }/* k = 5 j = 5 x = 2 y = 8 */

3.3 reinterpret_cast

reinterpret_cast強制類型轉換:

  • 用于指針類型間的強制轉換。
  • 用于整數和指針類型間的強制轉換。
  • 引用之間的轉換。

目標類型必須是一個指針、引用、算術類型、函數指針!

忠告:濫用 reinterpret_cast 運算符可能很容易帶來風險。 除非所需轉換本身是低級別的,否則應使用其他強制轉換運算符之一。

#include <iostream>using namespace std;class Animal { public:void cry() {cout << "動物叫" << endl;} };class Cat :public Animal { public:void cry(){cout << "喵喵瞄" << endl;}};class Dog :public Animal { public:void cry(){cout << "汪汪汪" << endl;}};int main(void) {//用法一 數值與指針之間的轉換int* p = reinterpret_cast<int*>(0x99999);int val = reinterpret_cast<int>(p);//用法二 不同類型指針和引用之間的轉換Dog dog1;Animal* a1 = &dog1;a1->cry();Dog* dog1_p = reinterpret_cast<Dog*>(a1);Dog* dog2_p = static_cast<Dog*>(a1); //如果能用static_cast ,static_cast 優先//Cat* cat1_p = static_cast<Cat*>(a1);//Cat* cat2_p = static_cast<Cat*>(dog1_p);//NO! 不同類型指針轉換不能使用static_castCat* cat2_p = reinterpret_cast<Cat*>(dog1_p);Animal& a2 = dog1;Dog& dog3 = reinterpret_cast<Dog&>(a2);//引用強轉用法,不同類型之間的引用也可以轉換dog1_p->cry();dog2_p->cry();cat2_p->cry();system("pause");return 0; }

3.4 dynamic_cast

dynamic_cast強制類型轉換:

  • 用于有繼承關系的類指針之間轉換。
  • 用于有交叉關系的類指針之間的轉換。
  • 具有類型檢查的功能。
  • 需要虛函數的支持。

dynamic是與繼承相關的類型轉換關鍵字,dynamic_cast要求相關的類中必須有虛函數。用于直接或間接繼承關系的指針(引用之間)。

對于指針:

  • 轉換成功:得到目標類型指針。
  • 轉換失敗:得到一個空指針。

對于引用:

  • 轉換成功:得到目標類型的引用。
  • 轉換失敗:得到一個異常操作信息。

編譯器會檢查dynamic_cast的使用是否正確,類型轉換的結果只能在運行階段才能得到。

dynamic的使用:

#include <iostream>using namespace std;class Animal { public:virtual void cry() = 0; };class Cat :public Animal { public:void cry(){cout << "喵喵瞄" << endl;}void play(){cout << "爬爬樹"<<endl;}};class Dog :public Animal { public:void cry(){cout << "汪汪汪" << endl;}void play(){cout << "溜達溜達" << endl;}};void animalPlay(Animal& animal) {animal.cry();try {Dog& pDog = dynamic_cast<Dog&>(animal);pDog.play();}catch (std::bad_cast bc) {cout << "不是狗,那應該是貓" << endl;}try {Cat& pCat = dynamic_cast<Cat&>(animal);pCat.play();}catch (std::bad_cast bc) {cout << "不是貓,那應該是上面的狗" << endl;}}void animalPlay(Animal* animal) {animal->cry();Dog* pDog = dynamic_cast<Dog*>(animal);if (pDog) {pDog->play();}else {//pDog == NULLcout << "不是狗,別騙我!" << endl;}Cat* pCat = dynamic_cast<Cat*>(animal);if (pCat) {pCat->play();}else {//pDog == NULLcout << "不是貓,別騙我!" << endl;} }int main(void) {Dog* dog1 = new Dog();Animal* a1 = dog1;//animalPlay(a1);Dog dog2;animalPlay(dog2);Cat* cat1 = new Cat();Animal* a2 = cat1;//animalPlay(a2);Cat cat2;animalPlay(cat2);system("pause");return 0; }

新式類型轉換以C++關鍵字的方式出現:

  • 編譯器能夠幫助檢查潛在的問題;
  • 非常方便的在代碼中定位;
  • 支持動態類型識別(dynamic_cast)。

3.5 類型轉換使用建議

1)static_cast靜態類型轉換,編譯的時c++編譯器會做編譯時的類型檢查;隱式轉換;基本類型轉換,父子類之間合理轉換。

2)若不同類型之間,進行強制類型轉換,用reinterpret_cast<>() 進行重新解釋。建議:C語言中能隱式類型轉換的,在c++中可用 static_cast<>()進行類型轉換。因C++編譯器在編譯檢查一般都能通過;C語言中不能隱式類型轉換的,在c++中可以用 reinterpret_cast<>() 進行強制類型解釋。

總結:static_cast<>()和reinterpret_cast<>() 基本上把C語言中的 強制類型轉換給覆蓋,注意reinterpret_cast<>()很難保證移植性。

3)dynamic_cast<>(),動態類型轉換,安全的虛基類和子類之間轉換;運行時類型檢查。
4)const_cast<>(),去除變量的只讀屬性。

最后的忠告:程序員必須清楚的知道: 要轉的變量,類型轉換前是什么類型,類型轉換后是什么類型,轉換后有什么后果。

C++大牛建議:一般情況下,不建議進行類型轉換;避免進行類型轉換。


參考資料:

  • C語言進階剖析教程
  • C++深度解析教程
  • C/C++從入門到精通-高級程序員之路【奇牛學院】
  • 總結

    以上是生活随笔為你收集整理的C/C++中的数据类型转换的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。