10-C語言進制和位運算-指趣學院

進制基本概念

  • 什么是進制?

    • 進制是一種計數的方式,數值的表示形式
  • 常見的進制

    • 十進制、二進制、八進制、十六進制
  • 進制書寫的格式和規律

    • 十進制 0、1、2、3、4、5、6、7、8、9 逢十進一
    • 二進制 0、1 逢二進一
      • 書寫形式:需要以0b或者0B開頭,例如: 0b101
    • 八進制 0、1、2、3、4、5、6、7 逢八進一
      • 書寫形式:在前面加個0,例如: 061
    • 十六進制 0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F 逢十六進一
    • 書寫形式:在前面加個0x或者0X,例如: 0x45
  • 練習

    • 1.用不同進制表示如下有多少個方格
    • 2.判斷下列數字是否合理
    00011  0x001  0x7h4  10.98  0986  .089-109
    +178  0b325  0b0010  0xffdc 96f 96.0f 96.oF  -.003
    

進制轉換

  • 10 進制轉 2 進制
    • 除2取余, 余數倒序; 得到的序列就是二進制表示形式
    • 例如: 將十進制(97) 10轉換為二進制數

  • 2 進制轉 10 進制
    • 每一位二進制進制位的值 * 2的當前索引次冪; 再將所有位求出的值相加
    • 例如: 將二進制01100100轉換為十進制
    01100100
    索引從右至左, 從零開始
    第0位: 0 * 2^0 = 0;
    第1位: 0 * 2^1 = 0;
    第2位: 1 * 2^2 = 4;
    第3位: 0 * 2^3 = 0;
    第4位: 0 * 2^4 = 0;
    第5位: 1 * 2^5 = 32;
    第6位: 1 * 2^6 = 64;
    第7位: 0 * 2^7 = 0;
    最終結果為: 0 + 0 + 4 + 0 + 0 + 32 + 64 + 0 = 100
    

  • 2 進制轉 8 進制
    • 三個二進制位代表一個八進制位, 因為3個二進制位的最大值是7,而八進制是逢8進1
    • 例如: 將二進制01100100轉換為八進制數
    從右至左每3位劃分為8進制的1位, 不夠前面補0
    001 100 100
    第0位: 100 等于十進制 4
    第1位: 100 等于十進制 4
    第2位: 001 等于十進制 1
    最終結果: 144就是轉換為8進制的值
    

  • 2 進制轉 16 進制
    • 四個二進制位代表一個十六進制位,因為4個二進制位的最大值是15,而十六進制是逢16進1
    • 例如: 將二進制01100100轉換為十六進制數
    從右至左每4位劃分為16進制的1位, 不夠前面補0
    0110 0100
    第0位: 0100 等于十進制 4
    第1位: 0110 等于十進制 6
    最終結果: 64就是轉換為16進制的值
    

  • 其它進制轉換為十進制
    • 系數 * 基數 ^ 索引 之和
        十進制           -->          十進制
       12345   =  10000 + 2000 + 300 + 40 + 5
               =  (1 * 10 ^ 4)  + (2 * 10 ^ 3) + (3 * 10 ^ 2) + (4 * 10 ^ 1) + (5 * 10 ^ 0)
               =  (1 * 10000) + (2 + 1000) + (3 * 100) + (4 * 10) + (5 * 1)
               =  10000 + 2000 + 300 + 40 + 5
               =  12345
       
       規律:
       其它進制轉換為十進制的結果 = 系數 * 基數 ^ 索引 之和
       
       系數: 每一位的值就是一個系數 
       基數: 從x進制轉換到十進制, 那么x就是基數
       索引: 從最低位以0開始, 遞增的數
    
       二進制        -->      十進制
       543210
       101101 = (1 * 2 ^ 5) + (0 * 2 ^ 4) + (1 * 2 ^ 3) + (1 * 2 ^ 2) + (0 * 2 ^ 1) + (1 * 2 ^ 0)
              = 32 + 0 + 8 + 4 + 0 + 1
              = 45
       
       八進制        -->     十進制
       016  =   (0 * 8 ^ 2) + (1 * 8 ^ 1) + (6 * 8 ^ 0)
            =    0  + 8 + 6
            =    14
       
       十六進制      -->      十進制
       0x11f =  (1 * 16 ^ 2) + (1 * 16 ^ 1) + (15 * 16 ^ 0)
             =   256  + 16 + 15
             =   287
    

  • 十進制快速轉換為其它進制
    • 十進制除以基數取余, 倒敘讀取
       十進制        -->     二進制
       100          -->    1100100
       100 / 2   = 50     0
       50  / 2   = 25     0
       25  / 2   = 12     1
       12  / 2   = 6      0
       6   / 2   = 3      0
       3   / 2   = 1      1
       1   / 2   = 0      1
       
       
       十進制        -->     八進制
       100          -->     144
       100 / 8    = 12    4
       12  / 8    = 1     4
       1   / 8    = 0     1
       
       十進制        -->     十六進制
       100          --> 64
       100 / 16   =  6    4
       6   / 16   =  0    6
    

十進制小數轉換為二進制小數

  • 整數部分,直接轉換為二進制即可
  • 小數部分,使用"乘2取整,順序排列"
    • 用2乘十進制小數,可以得到積,將積的整數部分取出,再用2乘余下的小數部分,直到積中的小數部分為零,或者達到所要求的精度為止
    • 然后把取出的整數部分按順序排列起來, 即是小數部分二進制
  • 最后將整數部分的二進制和小數部分的二進制合并起來, 即是一個二進制小數
  • 例如: 將12.125轉換為二進制
// 整數部分(除2取余)
  12
/  2
------
   6    // 余0
/  2
------
   3    // 余0
/  2
------
   1   // 余1
/  2
------
  0   // 余1
//12 --> 1100
  
// 小數部分(乘2取整數積)
  0.125
*     2
  ------
   0.25  //0
   0.25
*     2
  ------
    0.5  //0
    0.5
*     2
  ------
    1.0  //1
    0.0
// 0.125 --> 0.001

// 12.8125 --> 1100.001

二進制小數轉換為十進制小數

  • 整數部分按照二進制轉十進制即可
  • 小數部分從最高位開始乘以2的負n次方, n從1開始
  • 例如: 將 1100.001轉換為十進制
// 整數部分(乘以2的n次方, n從0開始)
0 * 2^0 = 0
0 * 2^1 = 0
1 * 2^2 = 4
1 * 2^3 = 8
 // 1100 == 8 + 4 + 0 + 0 == 12

// 小數部分(乘以2的負n次方, n從0開始)
0 * (1/2) = 0
0 * (1/4) = 0
1 * (1/8) = 0.125
// .100 == 0 + 0 + 0.125 == 0.125

// 1100.001  --> 12.125
  • 練習:
    • 將0.8125轉換為二進制
    • 將0.1101轉換為十進制
  0.8125
*      2
--------
   1.625  // 1
   0.625
*      2
--------
    1.25 // 1
    0.25
*      2
--------
     0.5 // 0
*      2
--------
    1.0 // 1
    0.0

// 0. 8125  --> 0.1101
1*(1/2) = 0.5
1*(1/4)=0.25
0*(1/8)=0
1*(1/16)=0.0625

//0.1101 --> 0.5 + 0.25 + 0 + 0.0625 == 0.8125

原碼反碼補碼

  • 計算機只能識別0和1, 所以計算機中存儲的數據都是以0和1的形式存儲的
  • 數據在計算機內部是以補碼的形式儲存的, 所有數據的運算都是以補碼進行的
  • 正數的原碼、反碼和補碼
    • 正數的原碼、反碼和補碼都是它的二進制
    • 例如: 12的原碼、反碼和補碼分別為
      • 0000 0000 0000 0000 0000 0000 0000 1100
      • 0000 0000 0000 0000 0000 0000 0000 1100
      • 0000 0000 0000 0000 0000 0000 0000 1100
  • 負數的原碼、反碼和補碼
    • 二進制的最高位我們稱之為符號位, 最高位是0代表是一個正數, 最高位是1代表是一個負數
    • 一個負數的原碼, 是將該負數的二進制最高位變為1
    • 一個負數的反碼, 是將該數的原碼除了符號位以外的其它位取反
    • 一個負數的補碼, 就是它的反碼 + 1
    • 例如: -12的原碼、反碼和補碼分別為
      0000 0000 0000 0000 0000 0000 0000 1100 // 12二進制
      1000 0000 0000 0000 0000 0000 0000 1100 // -12原碼
      1111 1111 1111 1111 1111 1111 1111 0011  // -12反碼
      1111 1111 1111 1111 1111 1111 1111 0100 // -12補碼
    
  • 負數的原碼、反碼和補碼逆向轉換
    • 反碼 = 補碼-1
    • 原碼= 反碼最高位不變, 其它位取反
      1111 1111 1111 1111 1111 1111 1111 0100 // -12補碼
      1111 1111 1111 1111 1111 1111 1111 0011  // -12反碼
      1000 0000 0000 0000 0000 0000 0000 1100 // -12原碼
    

  • 為什么要引入反碼和補碼
    • 在學習本節內容之前,大家必須明白一個東西, 就是計算機只能做加法運算, 不能做減法和乘除法, 所以的減法和乘除法內部都是用加法來實現的
      • 例如: 1 - 1, 內部其實就是 1 + (-1);
      • 例如: 3 * 3, 內部其實就是 3 + 3 + 3;
      • 例如: 9 / 3, 內部其實就是 9 + (-3) + (-3) + (-3);
    • 首先我們先來觀察一下,如果只有原碼會存儲什么問題
      • 很明顯, 通過我們的觀察, 如果只有原碼, 1-1的結果不對
        // 1 + 1
         0000 0000 0000 0000 0000 0000 0000 0001 // 1原碼
        +0000 0000 0000 0000 0000 0000 0000 0001 // 1原碼
         ---------------------------------------
         0000 0000 0000 0000 0000 0000 0000 0010  == 2
      
         // 1 - 1; 1 + (-1);
         0000 0000 0000 0000 0000 0000 0000 0001 // 1原碼
        +1000 0000 0000 0000 0000 0000 0000 0001 // -1原碼
         ---------------------------------------
         1000 0000 0000 0000 0000 0000 0000 0010 == -2
      
    • 正是因為對于減法來說,如果使用原碼結果是不正確的, 所以才引入了反碼
      • 通過反碼計算減法的結果, 得到的也是一個反碼;
      • 將計算的結果符號位不變其余位取反,就得到了計算結果的原碼
      • 通過對原碼的轉換, 很明顯我們計算的結果是-0, 符合我們的預期
      // 1 - 1; 1 + (-1);
      0000 0000 0000 0000 0000 0000 0000 0001 // 1反碼
      1111 1111 1111 1111 1111 1111 1111 1110   // -1反碼
      ---------------------------------------
      1111 1111 1111 1111 1111 1111 1111 1111 // 計算結果反碼
      1000 0000 0000 0000 0000 0000 0000 0000 // 計算結果原碼 == -0
    
    • 雖然反碼能夠滿足我們的需求, 但是對于0來說, 前面的負號沒有任何意義, 所以才引入了補碼
      • 由于int只能存儲4個字節, 也就是32位數據, 而計算的結果又33位, 所以最高位溢出了,符號位變成了0, 所以最終得到的結果是0
      // 1 - 1; 1 + (-1);
      0000 0000 0000 0000 0000 0000 0000 0001 // 1補碼
      1111 1111 1111 1111 1111 1111 1111 1111   // -1補碼
      ---------------------------------------
     10000 0000 0000 0000 0000 0000 0000 0000 // 計算結果補碼
      0000 0000 0000 0000 0000 0000 0000 0000 //  == 0
    

位運算符

  • 程序中的所有數據在計算機內存中都是以二進制的形式儲存的。
  • 位運算就是直接對整數在內存中的二進制位進行操作
  • C語言提供了6個位操作運算符, 這些運算符只能用于整型操作數
符號 名稱 運算結果
& 按位與 同1為1
| 按位或 有1為1
^ 按位異或 不同為1
~ 按位取反 0變1,1變0
<< 按位左移 乘以2的n次方
>> 按位右移 除以2的n次方

  • 按位與:
    • 只有對應的兩個二進位均為1時,結果位才為1,否則為0
    • 規律: 二進制中,與1相&就保持原位,與0相&就為0
9&5 = 1

 1001
&0101
------
 0001

  • 按位或:
    • 只要對應的二個二進位有一個為1時,結果位就為1,否則為0
9|5 = 13

 1001
|0101
------
 1101

  • 按位異或
    • 當對應的二進位相異(不相同)時,結果為1,否則為0
    • 規律:
      • 相同整數相的結果是0。比如55=0
      • 多個整數相^的結果跟順序無關。例如: 567=576
      • 同一個數異或另外一個數兩次, 結果還是那個數。例如: 577 = 5
9^5 = 12

 1001
^0101
------
 1100

  • 按位取反
    • 各二進位進行取反(0變1,1變0)
~9 =-10
0000 0000 0000 0000 0000 1001 // 取反前
1111 1111 1111 1111 1111 0110 // 取反后

// 根據負數補碼得出結果
1111 1111 1111 1111 1111 0110 // 補碼
1111 1111 1111 1111 1111 0101 // 反碼
1000 0000 0000 0000 0000 1010 // 源碼 == -10

  • 位運算應用場景:
    • 判斷奇偶(按位或)
       偶數: 的二進制是以0結尾
       8   -> 1000
       10  -> 1010
       
       奇數: 的二進制是以1結尾
       9   -> 1001
       11  -> 1011
    
       任何數和1進行&操作,得到這個數的最低位
       1000
      &0001
       -----
       0000  // 結果為0, 代表是偶數
    
       1011
      &0001
       -----
       0001 // 結果為1, 代表是奇數
    
    • 權限系統
      enum Unix {
        S_IRUSR = 256,// 100000000 用戶可讀
        S_IWUSR = 128,//  10000000 用戶可寫
        S_IXUSR = 64,//    1000000 用戶可執行
        S_IRGRP = 32,//     100000 組可讀
        S_IWGRP = 16,//      10000 組可寫
        S_IXGRP = 8,//        1000 組可執行
        S_IROTH = 4,//         100 其它可讀
        S_IWOTH = 2,//          10 其它可寫
        S_IXOTH = 1 //           1 其它可執行
       };
    // 假設設置用戶權限為可讀可寫
    printf("%d\n", S_IRUSR | S_IWUSR); // 384 // 110000000
    
    • 交換兩個數的值(按位異或)
     a = a^b;
     b = b^a;
     a = a^b;
    

  • 按位左移
    • 把整數a的各二進位全部左移n位,高位丟棄,低位補0
      • 由于左移是丟棄最高位,0補最低位,所以符號位也會被丟棄,左移出來的結果值可能會改變正負性
    • 規律: 左移n位其實就是乘以2的n次方
2<<1; //相當于 2 *= 2 // 4
  0010
<<0100

2<<2; //相當于 2 *= 2^2; // 8
  0010
<<1000
  • 按位右移
    • 把整數a的各二進位全部右移n位,保持符號位不變
      • 為正數時, 符號位為0,最高位補0
      • 為負數時,符號位為1,最高位是補0或是補1(取決于編譯系統的規定)
    • 規律: 快速計算一個數除以2的n次方
2>>1; //相當于 2 /= 2 // 1
  0010
>>0001
4>>2; //相當于 4 /= 2^2 // 1
  0100
>>0001
  • 練習:
    • 寫一個函數把一個10進制數按照二進制格式輸出
#include <stdio.h>
void printBinary(int num);
int main(int argc, const char * argv[]) {
    printBinary(13);
}
void printBinary(int num){
    int len = sizeof(int)*8;
    int temp;
    for (int i=0; i<len; i++) {
        temp = num; //每次都在原數的基礎上進行移位運算
        temp = temp>>(31-i); //每次移動的位數
        int t = temp&1; //取出最后一位
        if(i!=0&&i%4==0)printf(" "); printf("%d",t);
    }
}

變量內存分析

  • 內存模型
    • 內存模型是線性的(有序的)
    • 對于 32 機而言,最大的內存地址是2^32次方bit(4294967296)(4GB)
    • 對于 64 機而言,最大的內存地址是2^64次方bit(18446744073709552000)(171億GB)
  • CPU 讀寫內存
    • CPU 在運作時要明確三件事
      • 存儲單元的地址(地址信息)
      • 器件的選擇,讀 or 寫 (控制信息)
      • 讀寫的數據 (數據信息)
  • 如何明確這三件事情
    • 通過地址總線找到存儲單元的地址
    • 通過控制總線發送內存讀寫指令
    • 通過數據總線傳輸需要讀寫的數據
  • 地址總線: 地址總線寬度決定了CPU可以訪問的物理地址空間(尋址能力)
    • 例如: 地址總線的寬度是1位, 那么表示可以訪問 0 和 1的內存
    • 例如: 地址總線的位數是2位, 那么表示可以訪問 00、01、10、11的內存
  • 數據總線: 數據總線的位數決定CPU單次通信能交換的信息數量
    • 例如: 數據總線:的寬度是1位, 那么一次可以傳輸1位二進制數據
    • 例如: 地址總線的位數是2位,那么一次可以傳輸2位二進制數據
  • 控制總線: 用來傳送各種控制信號
  • 寫入流程
    • CPU 通過地址線將找到地址為 FFFFFFFB 的內存
    • CPU 通過控制線發出內存寫入命令,選中存儲器芯片,并通知它,要其寫入數據。
    • CPU 通過數據線將數據 8 送入內存 FFFFFFFB 單元中


  • 讀取流程
    • CPU 通過地址線將找到地址為 FFFFFFFB 的內存
    • CPU 通過控制線發出內存讀取命令,選中存儲器芯片,并通知它,將要從中讀取數據
    • 存儲器將 FFFFFFFB 號單元中的數據 8 通過數據線送入 CPU寄存器中


  • 變量的存儲原則
    • 先分配字節地址大內存,然后分配字節地址小的內存(內存尋址是由大到小)
    • 變量的首地址,是變量所占存儲空間字節地址(最小的那個地址 )
    • 低位保存在低地址字節上,高位保存在高地址字節上
    10的二進制: 0b00000000 00000000 00000000 00001010
               高字節←                        →低字節
    

char類型內存存儲細節

  • char類型基本概念
    • char是C語言中比較靈活的一種數據類型,稱為“字符型”
    • char類型變量占1個字節存儲空間,共8位
    • 除單個字符以外, C語言的的轉義字符也可以利用char類型存儲
字符 意義
\b 退格(BS)當前位置向后回退一個字符
\r 回車(CR),將當前位置移至本行開頭
\n 換行(LF),將當前位置移至下一行開頭
\t 水平制表(HT),跳到下一個 TAB 位置
\0 用于表示字符串的結束標記
\ 代表一個反斜線字符 \
\" 代表一個雙引號字符"
\' 代表一個單引號字符'
  • char型數據存儲原理
    • 計算機只能識別0和1, 所以char類型存儲數據并不是存儲一個字符, 而是將字符轉換為0和1之后再存儲
    • 正是因為存儲字符類型時需要將字符轉換為0和1, 所以為了統一, 老美就定義了一個叫做ASCII表的東東
    • ASCII表中定義了每一個字符對應的整數


    char ch1 = 'a'; 
    printf("%i\n", ch1); // 97

    char ch2 = 97;
    printf("%c\n", ch2); // a
  • char類型注意點
    • char類型占一個字節, 一個中文字符占3字節(unicode表),所有char不可以存儲中文
    char c = '我'; // 錯誤寫法
    
    • 除轉義字符以外, 不支持多個字符
    char ch = 'ab'; // 錯誤寫法
    
    • char類型存儲字符時會先查找對應的ASCII碼值, 存儲的是ASCII值, 所以字符6和數字6存儲的內容不同
    char ch1 = '6'; // 存儲的是ASCII碼 64
    char ch2 = 6; //  存儲的是數字 6
    
  • 練習
    • 定義一個函數, 實現輸入一個小寫字母,要求轉換成大寫輸出

類型說明符

  • 類型說明符基本概念
    • C語言提供了說明長度說明符號位的兩種類型說明符, 這兩種類型說明符一共有4個:
      • short 短整型 (說明長度)
      • long 長整型 (說明長度)
      • signed 有符號型 (說明符號位)
      • unsigned 無符號型 (說明符號位)
  • 這些說明符一般都是用來修飾int類型的,所以在使用時可以省略int
  • 這些說明符都屬于C語言關鍵字

short和long

  • short和long可以提供不同長度的整型數,也就是可以改變整型數的取值范圍。
    • 在64bit編譯器環境下,int占用4個字節(32bit),取值范圍是-2^31 ~ 2^31-1;
    • short占用2個字節(16bit),取值范圍是-2^15 ~ 2^15-1;
    • long占用8個字節(64bit),取值范圍是-2^63 ~ 2^63-1
  • 總結一下:在64位編譯器環境下:
    • short占2個字節(16位)
    • int占4個字節(32位)
    • long占8個字節(64位)。
    • 因此,如果使用的整數不是很大的話,可以使用short代替int,這樣的話,更節省內存開銷。
  • 世界上的編譯器林林總總,不同編譯器環境下,int、short、long的取值范圍和占用的長度又是不一樣的。比如在16bit編譯器環境下,long只占用4個字節。不過幸運的是,ANSI \ ISO制定了以下規則:
    • short跟int至少為16位(2字節)
    • long至少為32位(4字節)
    • short的長度不能大于int,int的長度不能大于long
    • char一定為為8位(1字節),畢竟char是我們編程能用的最小數據類型
  • 可以連續使用2個long,也就是long long。一般來說,long long的范圍是不小于long的,比如在32bit編譯器環境下,long long占用8個字節,long占用4個字節。不過在64bit編譯器環境下,long long跟long是一樣的,都占用8個字節。
#include <stdio.h>

int main()
{
    // char占1個字節, char的取值范圍 -2^7~2^7
    char num = 129;
    printf("size = %i\n", sizeof(num)); // 1
    printf("num = %i\n", num); // -127
    // short int 占2個字節, short int的取值范圍 -2^15~2^15-1
    short int num1 = 32769;// -32767
    printf("size = %i\n", sizeof(num1)); // 2
    printf("num1 = %hi\n", num1);

    // int占4個字節, int的取值范圍 -2^31~2^31-1
    int num2 = 12345678901;
    printf("size = %i\n", sizeof(num2)); // 4
    printf("num2 = %i\n", num2);

    // long在32位占4個字節, 在64位占8個字節
    long int num3 = 12345678901;
    printf("size = %i\n", sizeof(num3)); // 4或8
    printf("num3 = %ld\n", num3);

    // long在32位占8個字節, 在64位占8個字節 -2^63~2^63-1
    long long int num4 = 12345678901;
    printf("size = %i\n", sizeof(num4)); // 8
    printf("num4 = %lld\n", num4);
    
    // 由于short/long/long long一般都是用于修飾int, 所以int可以省略
    short num5 = 123;
    printf("num5 = %lld\n", num5);
    long num6 = 123;
    printf("num6 = %lld\n", num6);
    long long num7 = 123;
    printf("num7 = %lld\n", num7);
    return 0;
}

signed和unsigned

  • 首先要明確的:signed int等價于signed,unsigned int等價于unsigned
  • signed和unsigned的區別就是它們的最高位是否要當做符號位,并不會像short和long那樣改變數據的長度,即所占的字節數。
    • signed:表示有符號,也就是說最高位要當做符號位。但是int的最高位本來就是符號位,因此signed和int是一樣的,signed等價于signed int,也等價于int。signed的取值范圍是-2^31 ~ 2^31 - 1
    • unsigned:表示無符號,也就是說最高位并不當做符號位,所以不包括負數。
    • 因此unsigned的取值范圍是:0000 0000 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 1111 1111,也就是0 ~ 2^32 - 1
#include <stdio.h>

int main()
{
    // 1.默認情況下所有類型都是由符號的
    int num1 = 9;
    int num2 = -9;
    int num3 = 0;
    printf("num1 = %i\n", num1);
    printf("num2 = %i\n", num2);
    printf("num3 = %i\n", num3);

    // 2.signed用于明確說明, 當前保存的數據可以是有符號的, 一般情況下很少使用
    signed int num4 = 9;
    signed int num5 = -9;
    signed int num6 = 0;
    printf("num4 = %i\n", num4);
    printf("num5 = %i\n", num5);
    printf("num6 = %i\n", num6);

    // signed也可以省略數據類型, 但是不推薦這樣編寫
    signed num7 = 9;
    printf("num7 = %i\n", num7);
   

    // 3.unsigned用于明確說明, 當前不能保存有符號的值, 只能保存0和正數
    // 應用場景: 保存銀行存款,學生分數等不能是負數的情況
    unsigned int num8 = -9;
    unsigned int num9 = 0;
    unsigned int num10 = 9;
    // 注意: 不看怎么存只看怎么取
    printf("num8 = %u\n", num8);
    printf("num9 = %u\n", num9);
    printf("num10 = %u\n", num10);
    return 0;
}
  • 注意點:
    • 修飾符號的說明符可以和修飾長度的說明符混合使用
    • 相同類型的說明符不能混合使用
    signed short int num1 = 666;
    signed unsigned int num2 = 666; // 報錯
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容