在Java中創建多線程,往往都要通過Thread類來實現,今天學習下Java中創建多線程的三種方法[1]。 1.繼承Thread類 通過繼承 Thread類 實現多線程。 主要方法: 1.void run(), 線程開啟後,方法將被調用執行 2.void start(), 使此線程開始執行, Jav ...
C語言【進位、原反補碼、數據類型】
1、二進位、八進位、十進位、十六進位在C語言中的使用(賦值及輸出)?
/**
二進位
賦值時以 0b 或 0B 開頭;
輸出時沒有所屬占位符, 十六進位整數輸出也比較直觀
*/
int num_bin = 0b110;
printf("%d\n", num_bin); // 以十進位整數形式輸出
//其他進位輸出形式略,總之就是沒有二進位形式的輸出
/**
八進位
賦值時以0(零)開頭;
占位符:%o (小寫字母o , 八進位整數)
*/
int num_oct = 0123;
printf("%o\n", num_oct); // 以八進位整數形式輸出
/**
十進位
賦值時正常表示
占位符:%d 表示輸出形式為十進位整數
*/
int num_deci = 123456;
printf("%d\n", num_deci);
/**
十六進位
以0x或0X開頭
占位符: %x 輸出十六進位整數(A-F輸出為小寫)
%X 輸出十六進位整數(A-F輸出為大寫)
%#x 輸出0x樣式十六進位整數
%#X 輸出0X樣式十六進位整數
*/
int num_hex = 0xff;
printf("%x\n", num_hex);
printf("%#x\n", num_hex);
printf("%#X\n", num_hex);
拓展問題:有沒有浮點類型二/八/十六進位的數的展示 ?輸出呢?
似乎有,似乎用處不大。來一段:
float hex_float = 0x1P3;
printf("hex_float = %f\n", hex_float); // 輸出為 hex_float = 8.000000
在這裡,0x1P3
是一種用科學計數法表示十六進位浮點數的方式。在這個例子中,1P3
表示1乘以2的3次方,也就是8。
2、進位轉換略。 遺留問題: 浮點數的進位轉換?
3、機器數指一個數在電腦中存儲的二進位原樣;真值指按規則編碼後表示的值,比如1001這個二進位數,如果把最高位的1表示為符號位,則其真值為-1。
4、原反補碼是什麼及各自的轉換。
-
原碼:最高位表示符號位(0正、1負)的機器數。
-
反碼:正數反碼即原碼;負數反碼符號位不變,其他位取反。
反碼存在的意義就是為了求補碼。
-
補碼:正數的補碼即原碼;負數的補碼即反碼+1。
補碼存在的意義就是為使電腦運算更方便,因為電腦沒有設計減法器,聽說減法器不如用補碼更簡潔和高效。
補碼的設計原理是:讓負數原碼的絕對值和負數的補碼相加為全零(最高位溢出),這個補全後的數即為該存儲大小能表示的個數,2位元組的話這個數即為65536,這樣的話有效位數就全為0了。
比如:2+(-2)=0。 -2的補碼離有效位全0少2;+2離有效位全0多了2,對於有效位全0來說剛好互補。
這樣設計的好處為:作減法運算時,可視為正數和負數相加。
運算時,符號位也參與運算。
負數補碼轉原碼時,也可以直接取反後+1得到。
/** 下麵的代碼中 short 占兩個位元組,能表示65536個數,最高位溢出,有效位全0 -2的在記憶體中以補碼形式存儲,表示為十進位即為65534,要用%u輸出 也可以想-2離有效位全0即65536少2,即65534 */ unsigned short num_byte2 = -2; printf("%hu\n", num_byte2); // 輸出為 65534 hu表示無符號短整型 short num_byte2_1 = -2; printf("%hu\n", num_byte2_1); // 輸出為 65534
問題:參考上面的代碼,下麵的代碼為什麼會這樣子輸出?
unsigned short num_byte2 = -2; // 這一步將num_byte2轉換為65534 printf("%u\n", num_byte2); // 輸出為 65534 short num_byte2_1 = -2; // 在這一步num_byte2_1還是-2 printf("%u\n", num_byte2_1); // 輸出為 4294967294 轉換為無符號時short占不下了,按四個位元組來,就變成了 4294967296-2, 即 4294967294
5、基本數據類型
-
整型
-
短整型 short ---------- 2Byte
有符號短整型 signed short / short 占位符為: %hi 表示範圍:-32768到32767 字面量無尾綴
無符號短整型 unsigned short 占位符為: %hu 表示範圍:0到65535 字面量無尾綴表示
-
整型 int ---------- 16位機 2Byte; 32位機 4Byte
有符號整型 signed int / int 占位符: %d 表示範圍: 根據位數決定
一般拼寫上一個沒超過int範圍的數預設字面量的類型為int,除非在字面量後面加尾綴。
無符號整型 unsigned int 占位符 %u 表示範圍: 根據位數決定 字面量尾綴為u或U
-
長整型 long ----------- 32位機 4Byte; 64位機 8Byte 問題: 我64位機咋還是4Byte? windows的問題。Linux就是8個。不同系統使用的數據模型不同,導致long表示的範圍不能確定無二。
有符號長整型 signed long / long 占位符:%ld 表示範圍:不做掌握 字面量尾綴 l或L
無符號長整型 unsigned long 占位符: %lu 表示範圍:不做掌握 字面量尾綴lu或ul
-
長長整型 long long ------------ 8Byte
有符號長長整型 signed long long / long long 占位符: %lld 表示範圍:很大很大 字面量尾綴ll或LL
無符號長長整型 long long 占位符: %llu (l和u位置不可互換) 表示範圍:很大很大 字面量尾綴llu或LLU
註意:
任何系統的pointer(指針類型)位數和系統一致,比如64位即8Byte;
char、int、long long不隨系統改變;
儘量不使用long;
想確保int為4Byte可以使用stdint.h庫里的 int32_t 類型 -
-
浮點型
浮點型沒有無符號表示。浮點數的底層是三段存儲的,符號位、指數部分、有效部分,具體轉電腦組成原理查看。
-
單精度浮點型 float --------- 4Byte
表示範圍:1.2E-38 到 3.4E+38
有效小數位 6-9 字面量尾綴f或F,給不加小數點的字面常量尾綴f或F會報錯
占位符:對於printf(...)來說,單精度和雙精度都是 %f
C99打補丁後都可以為%lf 對於scanf(...)來說,單精度只能為 %f
-
雙精度浮點型 double --------- 8Byte
表示範圍 2.3E-308 到 1.7E+308
有效小數位數 15-18 加了小數點的字面量預設為double,無需尾綴
占位符:對於printf(...)來說,單精度和雙精度都是 %f
C99打補丁後都可以為%lf 對於scanf(...)來說,雙精度只能為 %lf
-
長雙精度浮點型 long double ------------ 32位機 10Byte; 64位機16Byte
表示範圍 很大很大
有效小數位數18位以上 字面量尾綴l或L,給不加小數點的字面常量尾綴f或F會表示為long
占位符:%Lf
-
浮點數列印時預設保留六位小數,可自行調整。如下:
double num_doub = 123456789.23956; // 註意: 這個保留的兩位是四捨五入而不是截取 (我用的gcc,別的編譯器沒試過) printf("%20.2lf\n", num_doub); // 總共輸出二十個字元,不夠前面補空格。小數點後保留兩位,如果整數位大於二十,則仍然完整輸出整數位,小數位保留兩位(註意.2後面是字母l,不是數字1) // %e 占位符可以輸出浮點數的科學計數法表示形式(適用float和double) 長雙用%Le(L大寫) double num_double2 = 123.4; printf("%e\n", num_double2);
-
-
字元型 char ------- 1Byte
占位符: %c
不能存中文字元,想存中文字元用指針或數組。
本質就是一個整數。不同設備把char預設為有符號/無符號的類型。一般是有符號,即 -128 到 127
-
布爾型 _Bool
C89標準沒有布爾類型。C99提供了 _Bool類型,只能存儲0或1,非0即存儲1,底層依然是整型。
6、數據類型轉換
-
隱式轉換(自動類型轉換)
short(2)/ char(1) ----> int(2/4) -----> unsigned int (2/4) --------> long(4/8) ------> unsigned long(4/8) ----> long long(8) ------> float(4) ------> double(8) ------> long double(10/32)
浮點轉整型有可能出現溢出(如果整數很大)或者 精度缺失
-
顯示轉換(強制類型轉換,略) 整數小轉大具體細節按補碼計算。涉及浮點數的小轉大不會。
float num_f = 12.3f; double num_dou = (double) num_f; printf("%lf\n", num_dou); // 輸出 12.300000
7、sizeof(...)的使用,格式占位符,返回的類型等。
sizeof(類型/變數名/字面量/表達式)
如果不是查看 類型或表達式 的大小,可以使用 sizeof 變數名/字面量
占位符為 %zu 或 %d
返回類型為size_t,根據系統決定實際類型。
返回類型的位元組個數,如果查看某個字面量的位元組占用個數,查的是它預設的使用類型位元組數。
8、補充
1. 轉義字元
\b 退格; \n 換行符; \r 回車符; \t 製表符; \加單雙引號或斜杠在特殊情況下轉義為它們本身等
2. C語言中非0即為真,-1也是真。
3. <stdint.h> 和 <stdbool.h> 提供的類型,略。
#include<stdio.h>
#include<stdint.h>
// 精確寬度整數類型
// 64位,很多電腦底層為long long , %d 輸出會數值錯亂
int64_t e1 = 4500000000;