網站首頁 編程語言 正文
一、C語言中的強制類型轉換
轉換的語法如下:
(Type) (Expression)
Type(Expression)
下面看一段C語言中粗暴的類型轉換的代碼:
#include <stdio.h>
typedef void(PF)(int);
struct Point
{
int x;
int y;
};
int main()
{
int v = 0x12345;
PF* pf = (PF*)v;
char c = char(v);
Point* p = (Point*)v;
pf(5);
printf("p->x = %d\n", p->x);
printf("p->y = %d\n", p->y);
return 0;
}
在C++的環境下編譯后就會發現:
二、C語言強制類型轉換存在的問題
過于粗暴
- 任意類型之間都可以進行轉換,編譯器很難判斷其正確性
難于定位
- 在源碼中無法快速定位所有使用強制類型轉換的語句
三、C++ 中的類型轉換
C++ 將強制類型轉換分為4種不同的類型:
C++強制類型轉換
static_cast | const_cast |
dynamic_cast | reinterpret_cast |
用法:xxx_cast<Type >( Expression )
static_cast 強制類型轉換
- 用于基本類型間的轉換
- 不能用于基本類型指針間的轉換
- 用于有繼承關系類對象之間的轉換和類指針之間的轉換
const_cast 強制類型轉換
- 用于去除變量的只讀屬性
- 強制轉換的目標類型必須是指針或引用
reinterpret_cast 強制類型轉換
- 用于指針類型間的強制轉換
- 用于整數和指針類型間的強制轉換
dynamic_cast 強制類型轉換
- 用于有繼承關系的類指針間的轉換
- 用于有交叉關系的類指針間的轉換
- 具有類型檢查的功能
- 需要虛函數的支持
??????下面看一段C++類型轉換代碼:
#include <stdio.h>
void static_cast_demo()
{
int i = 0x12345;
char c = 'c';
int* pi = &i;
char* pc = &c;
c = static_cast<char>(i);
//pc = static_cast<char*>(pi);
}
void const_cast_demo()
{
const int& j = 1;
int& k = const_cast<int&>(j);
const int x = 2;
int& y = const_cast<int&>(x);
//int z = const_cast<int>(x);
k = 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);
}
void reinterpret_cast_demo()
{
int i = 0;
char c = 'c';
int* pi = &i;
char* pc = &c;
pc = reinterpret_cast<char*>(pi);
pi = reinterpret_cast<int*>(pc);
pi = reinterpret_cast<int*>(i);
//c = reinterpret_cast<char>(i);
}
void dynamic_cast_demo()
{
int i = 0;
int* pi = &i;
//char* pc = dynamic_cast<char*>(pi);
}
int main()
{
static_cast_demo();
const_cast_demo();
reinterpret_cast_demo();
dynamic_cast_demo();
return 0;
}
下面為輸出結果:
注意程序注釋的4個地方,都是錯誤使用了類型轉換:
第一個地方:pc = static_cast<char*>(pi) 。錯誤在于static_cast 不能在基本類型指針之間相互轉換。
第二個地方:int z = const_cast<int>(x)。錯誤在于const_cast強制轉換的目標類型必須是指針或引用。
第三個地方:c = reinterpret_cast<char>(i)。錯誤在于 const_cast用于指針類型間的強制轉換,而不能用于基本類型。
第四個地方:char* pc = dynamic_cast<char*>(pi)。錯誤在于dynamic_cast需要虛函數的支持。
還有一個問題就是 x 和 y 值的問題。x 是一個真正意義上的常量,所以編譯期間值確定了就是2,但是編譯器要兼容 C語言,所以會給 x 在??臻g分配了4個字節的空間出來,使用 const_cast 作用于它就相當于給這 4個字節空間取了一個別名 y,令 y = 8,就相當于給這 4個字節??臻g中的 int 變量賦了一個值 8。所以打印出來的 x 和 y的地址值是一樣的。
四、小結
C 方式的強制類型轉換
- 過于粗暴
- 潛在的問題不易被發現
- 不易在代碼中定位
新式類型轉換以C++ 關鍵字的方式出現
- 編譯器能夠幫助檢查潛在的問題
- 非常方便的在代碼中定位
- 支持動態類型識別( dynamic_cast )
原文鏈接:https://blog.csdn.net/weixin_43129713/article/details/122694993
相關推薦
- 2022-03-22 docker安裝RabbitMQ詳細步驟_docker
- 2022-03-29 基于Python+Tkinter實現一個簡易計算器_python
- 2023-05-24 Python?的第三方調試庫????pysnooper???使用示例_python
- 2022-05-24 Python函數之zip函數的介紹與實際應用_python
- 2024-07-13 Spring AOP 基于注解的方式實現切面遍程
- 2022-11-03 一文詳解C++子類函數為什么不能重載父類函數_C 語言
- 2022-06-08 freertos實時操作系統臨界段保護開關中斷及進入退出_操作系統
- 2022-07-11 MongoDB分片方式及片鍵選擇
- 最近更新
-
- 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同步修改后的遠程分支