1. 程式人生 > >uint8_t / uint16_t / uint32_t /uint64_t資料型別詳解

uint8_t / uint16_t / uint32_t /uint64_t資料型別詳解

uint8_t / uint16_t / uint32_t /uint64_t 是什麼資料型別?

在nesc的程式碼中,你會看到很多你不認識的資料型別,比如uint8_t等。咋一看,好像是個新的資料型別,不過C語言(nesc是C的擴充套件)裡面好像沒有這種資料型別啊!怎麼又是u又是_t的?很多人有這樣的疑問。論壇上就有人問:以*_t結尾的型別是不是都是long型的?在baidu上查一下,才找到答案,這時才發覺原來自己對C掌握的太少。

那麼_t的意思到底表示什麼?具體的官方答案沒有找到,不過我覺得有個答案比較接近。它就是一個結構的標註,可以理解為type/typedef的縮寫,表示它是通過typedef定義的,而不是其它資料型別。

uint8_t,uint16_t,uint32_t等都不是什麼新的資料型別,它們只是使用typedef給型別起的別名,新瓶裝老酒的把戲。不過,不要小看了typedef,它對於你程式碼的維護會有很好的作用。比如C中沒有bool,於是在一個軟體中,一些程式設計師使用int,一些程式設計師使用short,會比較混亂,最好就是用一個typedef來定義,如:

typedef char bool;

一般來說,一個C的工程中一定要做一些這方面的工作,因為你會涉及到跨平臺,不同的平臺會有不同的字長,所以利用預編譯和typedef可以讓你最有效的維護你的程式碼。為了使用者的方便,C99標準的C語言硬體為我們定義了這些型別,我們放心使用就可以了。 按照posix標準,一般整形對應的*_t型別為:

1位元組     uint8_t
2位元組     uint16_t
4位元組     uint32_t
8位元組     uint64_t

這些資料型別是 C99 中定義的,具體定義在:/usr/include/stdint.h ISO C99: 7.18 Integer types <stdint.h>

/* There is some amount of overlap with <sys/types.h> as known by inet code */  
#ifndef __int8_t_defined  
# define __int8_t_defined  
typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; # if __WORDSIZE == 64 typedef long int int64_t; # else __extension__ typedef long long int int64_t; # endif #endif /* Unsigned. */ typedef unsigned char uint8_t; typedef unsigned short int uint16_t; #ifndef __uint32_t_defined typedef unsigned int uint32_t; # define __uint32_t_defined #endif #if __WORDSIZE == 64 typedef unsigned long int uint64_t; #else __extension__ typedef unsigned long long int uint64_t; #endif

注意:

必須小心 uint8_t 型別變數的輸出,例如如下程式碼,會輸出什麼呢?

uint8_t fieldID = 67;
cerr<< "field=" << fieldID <<endl;

結果發現是:field=C 而 不是我們所想的 field=67
這是由於:

typedef unsigned char uint8_t;

uint8_t 實際是一個 char, cerr << 會輸出 ASCII 碼是 67 的字元,而不是 67 這個數字.

因此,輸出 uint8_t 型別的變數實際輸出的是其對應的字元, 而不是真實數字.

若要輸出 67,則可以這樣:

cerr<< "field=" << (uint16_t) fieldID <<endl;

結果是:field=67

同樣: uint8_t 型別變數轉化為字串以及字串轉化為 uint8_t 型別變數都要注意, uint8_t型別變數轉化為字串時得到的會是ASCII碼對應的字元, 字串轉化為 uint8_t 變數時, 會將字串的第一個字元賦值給變數.

例如如下程式碼:

#include <iostream>  
#include <stdint.h>  
#include <sstream>  
using namespace std;  
  
  
int main()  
{  
    uint8_t fieldID = 67;  
  
    // uint8_t --> string  
    string s;  
    ostringstream strOStream;  
    strOStream << fieldID;  
    s = strOStream.str();  
    cerr << s << endl;  
      
    // string --> uint8_t  
    s = "65";   
    stringstream strStream;  
    strStream << s;  
    strStream >> fieldID;  
    strStream.clear();  
    cerr << fieldID << endl;  
}  

上述程式碼輸出的是:

C

6