C语言 类型转换
C語言
基礎概念:
類型轉換一般是為了解決如下的一些問題:
算術運算中或者邏輯判斷表達式中操作室,不匹配的時候。
賦值時,如果左右操作數類型不匹配。
函數傳遞進去的實參和匹配的形參對應不上。
函數返回的表達式的類型和函數返回類型不匹配。
出現上述問題我們一般會進行相應的類型轉換
否則編程在調試的時候會出現警告甚至報錯。
C語言中類型轉換主要分為兩種:
1. 隱式類型轉換
2. 顯示類型轉換
隱式類型轉換:編譯器自動將左右操作數變成相同類型去計算。
顯式類型轉換:程序開發者主觀上去將類型強制轉換。
在類型轉換的過程中首先明確 整值提升 的定義
整值提升:將出現的字符類型(char)和短整型(short)統一先提升為int型(特殊情況下,也會提升為unsigned int )
<一> 隱式類型轉換:
因為在C89 和 C99中有一點點的差別 這里就分開講解 。
C89:
整型類型:char,short, int, long ,long long (unsigned signed)
小數類型:float ,double
對應上述出現的那些問題進行說明:
一.算術運算中或者邏輯判斷表達式
(明確浮點值的優先值:long double > double > float)
- 如果左右操作數有浮點值。
1:如果一個操作數是long double 另一個操作數自動轉換為 long double 。
2:如果一個操作數為double 另一個自動靠向double。
3:如果一個操作數是float 另一個操作數自動轉換為float。
- 如果左右操作數沒有浮點值。
1:首先整值提升 不要存在字符類型和短整型。
2:從小到大轉換 int -> unsigned int-> long -> unsigned long。
3:如果兩個操作數 大小相等 并且一個是unsigned int 另一個是long int 則兩個全部轉換為 unsigned long int。
對于部分來說操作數浮點值和整型值混用
二.賦值語句
如果左值大小>=右值大小則自動轉換
1:如果左邊操作數類型存儲不下右邊操作數的值 則很危險 這個值為無效值
2:浮點值默認double 如果定義float a =3.14 轉換為float 會觸發double轉換為float 數據階段
3:將浮點值賦值給整型值,會發生數據丟失(丟失小數點后的數據)
C99:
相較于C89多了一些數據類型(bool long long int ,復數類型)。
C99將所有整型類型分等級:從高到低
1: long long int ,unsigned long long int
2: long int ,unsigned long int
3: int ,unsigned int
4: short int , unsigned short int
5: char , unsigned char , signed char
6: bool
使用的時候,具體分兩種情況:
一.操作數中帶浮點值
和C89一致(上面有講到,此處不在進行贅述)
二.操作數中如果不帶浮點值:
(下面4個條件,從上到下觸發,觸發其中一個則退出)
2.1: 如果兩個操作數都是有符號類型或者都是無符號類型,小的向大的轉化
2.2: 如果無符號操作數類型 >= 有符號操作數類型,則有符號向無符號操作數轉換
2.3: 如果有符號操作數類型 > 無符號操作數類型,如果無符號操作數能表示的范圍可以用有符號去表示,則無符號想有符號操作數轉化
2.4: 兩個同時向有符號類型的無符號類型轉化
特殊:如果兩個操作數大小相等,并且一個是unsigned int,另一個是long int,則兩個全部轉換為unsigned long int
三.所有的類型都可以轉化bool類型
如果值為0轉化為false 要不然則為true。
<二> 顯式類型轉換:
顯式類型轉換也稱作強制類型轉換。
一般寫法:(類型)表達式
類型->強行將表達式結果轉化的數據類型。
在強轉中的括號一般看作單目運算符,優先級最高。
驗證:
在驗證隱式類型轉換需要用到頭文件 :’‘typeinfo’'
驗證算術運算中的隱式類型轉換格式為:
printf("%s\n", typeid(類型+類型).name());
驗證代碼如下:
#include <stdio.h> #include <typeinfo> int main() {char c;short s;unsigned short us;//unsigned short int us;int i;unsigned int ui;long l;unsigned long ul;float f;double d;long double ld;printf("%d\n", sizeof(c+s));printf("%s\n", typeid(c+s).name());printf("%s\n", typeid(c+us).name());printf("%s\n", typeid(s+us).name());printf("%s\n", typeid(us+i).name());printf("%s\n", typeid(i+ui).name());printf("%s\n", typeid(i+l).name());printf("%s\n", typeid(ui+l).name());printf("%s\n", typeid(l+ul).name());printf("%s\n", typeid(f+s).name());printf("%s\n", typeid(f+c).name());printf("%s\n", typeid(f+i).name());printf("%s\n", typeid(d+ui).name());printf("%s\n", typeid(d+l).name());printf("%s\n", typeid(ld+s).name());printf("%s\n", typeid(ld+i).name());return 0; }驗證結果:
特別注意:printf("%s\n", typeid(ui + l).name()); 的這個類型為unsigned long int
強轉需要注意的問題:這里的括號,一般看做單目運算符,優先級最高
float f = (float)(a/b);//error float f = (float)a/b;//ok float f = a/(float)b;//ok float f = (float)a/(float)b;//ok總結
- 上一篇: matlab 曲线收敛,BP神经网络学习
- 下一篇: android培训讲师介绍,安卓培训讲师