型態轉型
(資料的)
Arvin Liu @ C-Sprout 2021
基本型態
C++的所有基本型態
(Fundamental types)
整數類
Integers
字元類
Characters
小數點類
Floating Point
異類
short
int
long
long long
unsigned short
unsigned (int)
unsigned long
unsigned long long
char
unsigned char
char16_t
char32_t
wchar_t
float
double
long double
bool
void
nullptr_t
紅色: 基礎預設型態,例如
- 1.23預設就是double。
- 1 預設就是int。
橘色: 你比較用的到的型態。
(一點補充) 科普沒有用不會講到的東西
型態 | 解釋 | 所占空間 |
---|---|---|
unsigned char | 沒什麼東西,就是可以存0~255的型態。 | 1 byte,同char。 |
char16_t | 為了存UTF-16 (unicode-16編碼)的型態。 | 2 bytes。 |
char32_t | 為了存UTF-32 (unicode-32編碼)的型態。 | 4bytes。 |
wchar_t | 在char16/32_t出現以前,存非常規的字的型態。 | 通常4bytes, 但windows是2bytes。 |
long double | 比double更大的浮點數型態。不常用且可能不支援。 | 通常12bytes。 |
long / unsigned long |
一個與作業系統操作息息相關的整數。大小如右邊所述。(long與指標的大小是相同的) | 32位元系統為4bytes, 64位元系統為8bytes。 |
void | 虛空(?) 不可以直接用void當型態,只能用他的指標型態宣告。常用在做各種指標的強制轉換。 | 1 byte。 |
nullptr_t | 特別的存在,指nullptr的型態。(因nullptr不是實物,所以nullptr的指標 (nullptr_t) 不算在"實物"指標的型態。) | 32位元系統為4bytes, 64位元系統為8bytes。 (也就是同指標大小) |
跟指標有關的東西可以等第二期資芽的指標課程~
查詢型態大小
沒看過這個型態也???
int ************* a;
sizeof(一個型態/東西)
#include <iostream>
using namespace std;
int main(){
cout << sizeof(int) << endl;
cout << sizeof(long long) << endl;
cout << sizeof(FILE) << endl;
cout << sizeof(string) << endl;
cout << sizeof(int *************) << endl;
return 0;
}
4
8
32
24
4 // 64-bit系統會是8
(在32-bit環境下執行的結果)
sizeof(一個型態/東西) = 這個型態/東西佔了多少bytes。
ㄨㄚˊ? 甚麼是bytes?
Special Thanks: Peipei @ sprout week 1
未來你可以自己做一個型態(?)
可以sizeof去衡量你的型態大小!
struct / class
布林值
Boolean
就是true 或 false
沒有true或false的疊加態
Boolean
#include <iostream>
int main(){
bool t = true; // 1
bool f = false; // 0
bool huh = (5 % 2 == 0);
if(huh){
std::cout << "huh?";
}else{
std::cout << "huh!";
}
}
huh!
只存true / false的一個神奇型態。
整數類
Integers
整數類
型態 | 所佔空間 | 數值範圍 |
程式表示 (要#include <climits>) |
---|---|---|---|
short |
2 bytes |
SHRT_MIN SHRT_MAX
|
|
unsigned short |
2 bytes |
USHRT_MAX
|
|
int | 4 bytes |
INT_MIN INT_MAX
|
|
unsigned |
4 bytes |
UINT_MAX
|
|
long long |
8 bytes |
LLONG_MIN LLONG_MAX
|
|
unsigned long long |
8 bytes |
ULLONG_MAX
|
可以用
來估算出題目數字會不會超出型態範圍
小數點類
Floating Point
浮點數需要知道的兩種型態
型態 | 所佔空間 |
程式表示 (要#include <cfloat>) |
---|---|---|
float | 4 bytes |
FLT_MIN FLT_MAX
|
double | 8 bytes |
DBL_MIN DBL_MAX
|
不要用 float 用 double!!!!!!!!
非數字的數字
奇怪的東西 | 意思 | 出現時機 |
---|---|---|
Nan |
他不是一個數字可以表達的。 (Not a number) |
sqrt(-1) |
Inf |
(Infinity) | 1.0 / 0 |
Ind |
沒有被定義。 (Indeterminate) |
inf / inf |
特殊的表達方式 - e
#include <iostream>
int main(){
double a = 1;
double b = 0.5;
double c = 1.27E1;
double d = 1.27e1;
double e = (int)1e5;
double f = 1.234e-2;
/* cout ommitted*/
return 0;
}
1
0.5
12.7
12.7
100000
0.01234
小數點可以用 <a>e<b>表示科學記號,
也就是
浮點數誤差問題
#include <iostream>
#include <cmath>
int main(){
if(0.1 + 0.2 == 0.3)
std::cout << "IQ180";
else
std::cout << "IQ3";
}
嗎?
IQ3
#include <iostream>
#include <cmath>
#define EPS 1e-7
int main(){
double A = 0.1 + 0.2;
double B = 0.3;
if(abs(A - B) < EPS)
std::cout << "IQ180";
else
std::cout << "IQ3";
}
IQ180
EPS (浮點數相對精度)
讓 = 的條件更寬鬆一點,只要在EPS內就當作一樣。
(EPS, epsilon, 一個很小的數字。)
轉型
不是這種轉型
所以我的帽子呢?
各種轉型
-
顯性轉型 / 強迫轉型
- 直接告訴程式要轉甚麼東西。
- 可以在前面加小括號轉型。
-
隱性轉型
- 讓程式自己處理,hehe。
- 通常出現在運算式裡面。
異形運算
不同型態的變數的運算 - 隱式轉型
Implicit Casting / Conversion
#include<iostream>
int main()
{
int x = 10; // integer x
char y = 'a'; // character c
// y 被隱式轉換成int
x = x + y;
// x 被隱式轉換成double
double z = x + 1.0;
return 0;
}
隱式轉型
隱轉 - 兩邊形態不一樣但是卻可以運算。
隱式轉換鏈
bool < char < int < unsigned < long long < float < double
整數 < 浮點數,少bit < 多bit,有號(+-) < 無號
兩個型態的運算,看誰比較小就會被轉換。
強制轉型
強迫某個數字轉換型態
強制轉型
總之就前面加小括號就好了。
7.2 (double型態) 強制轉換成 int型態。
cout << (int)7.2
// 7
Special Thanks: 竹區講師日月卦長
型態轉換問題表
型態轉換 | 舉例 | 可能的問題 |
---|---|---|
大浮點數 -> 小浮點數 | double -> float | 損失精準度。(超出未定義) |
浮點數 -> 整數 | float -> int | 損失小數部分。(超出未定義) |
大整數 -> 小整數 | long -> int | 只複製較低位元組的內容。 |
符號系列 <-> 沒有符號系列 | int <-> unsigned | 同大小直接overflow。 |
#include <iostream>
int main(){
float a = 123.4567890123456789;
int b = a;
int c = 1234567890123456789LL;
unsigned d = -1;
/* cout ommitted */
return 0;
}
123.457
123
2112454933
4294967295
小心隱式規則!!!!
#include <iostream>
int main(){
double x = 1 / 2;
double y = 1.0 / 2;
std::cout << x << std::endl;
std::cout << y << std::endl;
return 0;
}
為甚麼x是0,y卻是0.5呢?
小心0.999被砍掉!
#include <iostream>
#include <iomanip>
#include <cmath>
int main(){
double x = log(243) / log(3);
std::cout << x << std::endl;
std::cout << std::fixed << \
std::setprecision(16) << x << std::endl;
std::cout << (int)x << std::endl;
return 0;
}
5
4.9999999999999991
4
auto - 有必要這麼複雜嗎?
設型態好麻煩==
auto - 懶人工具
#include <iostream>
int main(){
auto z;
// compile error.
auto a=1.1;
// double. 浮點數預設 double。
auto a={1,2,3};
// initializer list,通常只可以拿來for-each。
}
不知道要放甚麼,那就放auto就好啦
請審慎使用<(_ _)>
Review
Review
- 看到除法先想要不要用double。
- 非特殊情況,不要用float。
- 會怕過程數字超範圍就開大一點 (如果空間夠的話)。
- 如果怕會轉歪全部用強制轉換
(用小括號+型態直接告訴程式要換甚麼。)
型態確認
auto到自己不知道那是甚麼型態 = =
typeid(東西).name()
#include <iostream>
#include <climits>
#include <cmath>
using namespace std;
int main(){
cout << sizeof(int) << endl;
cout << sizeof(long long) << endl;
cout << sizeof(FILE) << endl;
cout << sizeof(string) << endl;
cout << sizeof(int *************) << endl;
cout << typeid(int).name() << endl;
cout << typeid(long long).name() << endl;
cout << typeid(FILE).name() << endl;
cout << typeid(string).name() << endl;
cout << typeid(int *************).name() << endl;
return 0;
}
4
8
216
32
8
i
x
8_IO_FILE
NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
PPPPPPPPPPPPPi
資料型態 & 轉型
By Arvin Liu
資料型態 & 轉型
- 1,370