網站首頁 編程語言 正文
C語言中的類型轉換
在C語言中,如果賦值運算符左右兩側類型不同,或者形參與實參類型不匹配,或者返回值類型與接收返回值類型不一致時,就需要發生類型轉化,C語言中總共有兩種形式的類型轉換:隱式類型轉換和顯式類型轉換。
1.隱式類型轉化:編譯器在編譯階段自動進行,能轉就轉,不能轉就編譯失敗
2.顯式類型轉化:需要用戶自己處理
3.缺陷:轉換的可視性比較差,所有的轉換形式都是以一種相同形式書寫,難以跟蹤錯誤的轉換
int main()
{
int i = 1;
// 隱式類型轉換(意義相近的類型)
double d = i;
printf("%d, %.2f\n", i, d);
int* p = &i;
// 顯示的強制類型轉換(意義不相近的類型,值轉換后有意義)
int address = (int)p;
printf("%x, %d\n", p, address);
return 0;
}
為什么C++需要四種類型轉換
C風格的轉換格式很簡單,但是有不少缺點的:
1.隱式類型轉化有些情況下可能會出問題:比如數據精度丟失
2.顯式類型轉換將所有情況混合在一起,代碼不夠清晰
因此C++提出了自己的類型轉化風格,注意因為C++要兼容C語言,所以C++中還可以使用C語言的轉化風格。
C++強制類型轉換
標準C++為了加強類型轉換的可視性,引入了四種命名的強制類型轉換操作符:
static_cast、 reinterpret_cast、 const_cast、 dynamic_cast
static_cast
static_cast用于非多態類型的轉換(靜態轉換),編譯器隱式執行的任何類型轉換都可用static_cast,但它不能用于兩個不相關的類型進行轉換
int main()
{
double d = 12.34;
int a = static_cast<int>(d); // 意義相近的
cout << a << endl;
int* p = &a;
// 不支持的
//int address = static_cast<int>(p); // 意義不相近
return 0;
}
reinterpret_cast
reinterpret_cast操作符通常為操作數的位模式提供較低層次的重新解釋,用于將一種類型轉換為另一種不同的類型
int main()
{
double d = 12.34;
int a = static_cast<int>(d); // 意義相近
cout << a << endl;
int* p = &a;
// 不支持的
//int address = static_cast<int>(p);
int address = reinterpret_cast<int>(p); // 意義不相近
return 0;
}
const_cast
const_cast最常用的用途就是刪除變量的const屬性,方便賦值
int main()
{
// const int a = 2;
volatile const int a = 2;
int* p = const_cast<int*>(&a);
//int* p = (int*)&a;
*p = 3;
cout << a << endl; // 2
cout << *p << endl; // 3
return 0;
}
dynamic_cast
class A
{
public:
virtual void f(){}
public:
int _a = 0;
};
class B : public A
{
public:
int _b = 1;
};
// A*指針pa有可能指向父類,有可能指向子類
void fun(A* pa)
{
// 如果pa是指向子類,那么可以轉換,轉換表達式返回正確的地址
// 如果pa是指向父類,那么不能轉換,轉換表達式返回nullptr
B* pb = dynamic_cast<B*>(pa); // 安全的
//B* pb = (B*)pa; // 不安全
if (pb)
{
cout << "轉換成功" << endl;
pb->_a++;
pb->_b++;
cout << pb->_a << ":" << pb->_b << endl;
}
else
{
cout << "轉換失敗" << endl;
pa->_a++;
cout << pa->_a << endl;
}
}
// A 是父類 B是子類
int main()
{
// 父類對象無論如何都是不允許轉換成子類對象的
// A aa;
// B bb = dynamic_cast<B>(aa); // 不支持
// B bb = (B)aa; // 不支持
A aa;
B bb;
A* pa = &bb;
B* pb = dynamic_cast<B*>(pa);
//fun(nullptr);
return 0;
}
class A1
{
public:
virtual void f(){}
public:
int _a1 = 0;
};
class A2
{
public:
virtual void f(){}
public:
int _a2 = 0;
};
class B : public A1, public A2
{
public:
int _b = 1;
};
int main()
{
B bb;
A1* ptr1 = &bb;
A2* ptr2 = &bb;
cout << ptr1 << endl;
cout << ptr2 << endl << endl;
B* pb1 = (B*)ptr1;
B* pb2 = (B*)ptr2;
cout << pb1 << endl;
cout << pb2 << endl << endl;
B* pb3 = dynamic_cast<B*>(ptr1);
B* pb4 = dynamic_cast<B*>(ptr2);
cout << pb3 << endl;
cout << pb4 << endl << endl;
return 0;
}
原文鏈接:https://blog.csdn.net/weixin_54183294/article/details/128191955
相關推薦
- 2022-11-02 Python+eval函數實現動態地計算數學表達式詳解_python
- 2022-07-06 C語言全面梳理文件操作方法_C 語言
- 2022-05-12 Android Studio 崩潰一閃而過抓不到日志
- 2022-11-05 docker中nginx卸載、安裝、配置及掛載詳細教程_docker
- 2022-07-07 C++?opencv實現幾何圖形繪制_C 語言
- 2022-07-30 @Autowired實現的原理
- 2022-09-13 Go語言實現超時的三種方法實例_Golang
- 2022-04-18 pyinstaller打包后,配置文件無法正常讀取的解決_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支