What data type is uint8_t/uint16_t/uint32_t/uint64_t? It is often encountered in embedded programming.
First
Types ending with *_t
It is a structure annotation, which can be understood as the abbreviation of type/typedef, indicating that it is defined by typedef, not other data types.
Uint 8_t, uint 16_t, uint 32_t and so on are not new data types, they just use typedef to give the type alias, the trick of new bottled old wine. Nevertheless, don't underestimate typedef, it will be very useful for the maintenance of your code. For example, there is no bool in C, so in a software, some programmers use int, some programmers use short, it will be confusing, the best is to use a typedef to define, such as:
typedef char bool;
Generally speaking, a C project must do some work in this area, because you will involve cross-platform, different platforms will have different word lengths, so using precompiled and typedef can let you most effectively maintain your code. For the convenience of users, the C language hardware of C99 standard defines these types for us. We can safely use them.
According to posix standard, the corresponding *_t type of general shaping is:
1 byte uint8_t
2 bytes uint16_t
4 bytes uint32_t
8 bytes uint64_t
It seems that there is no such data type in C language, but in the process of practical application, it is found that many people have this representation in their code. In fact, uintX-t is defined by typedef. Pre-compiler and typedef can improve efficiency and facilitate code migration. The summary is as follows:
typedef unsigned char uint8_t; / / unsigned 8 digits
typedef signed char int8_t; / / signed 8 digits
typedef unsigned int uint 16_t; / unsigned 16 digits
typedef signed int int 16_t; / / signed 16 digits
typedef unsigned long uint32_t; / / unsigned 32 digits
typedef signed long int 32_t; / / signed 32 digits
Typeedef float float32; / single-precision floating-point number
Typeedef double float64; / double precision floating point number
Generally speaking, the corresponding *_t type of shaping is:
uint8_t is 1 byte.
uint16_t is 2 bytes
uint32_t is 4 bytes.
uint64_t is 8 bytes.
It is not difficult to see that uint8_t is defined by header file X.h. In fact, the compiler actually treats it as "char" and operates on character variables. For reference only, please point out any mistakes.
What data type is uint8_t/uint16_t/uint32_t/uint64_t?
These data types are defined in C99 and are specifically defined in: / 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
Format output:
unit64_t %llu
unit32_t %u
unit16_t %hu
Be careful:
You have to be careful about the output of uint8_t type variables, such as the following code, what will be output?
uint8_t fieldID = 67;
cerr<< "field=" << fieldID <<endl;
The result is: field=C, not field=67 as we think.
This is due to typedef unsigned char uint8_t;
uint8_t is actually a char, cerr will output the ASCII code as a character of 67, not a number of 67.
Therefore, a variable of type uint8_t actually outputs its corresponding character, not its real number.
To output 67, you can do this:
cerr<< "field=" << (uint16_t) fieldID <<endl;
The result is: field=67
Similarly: when uint8_t type variables are converted into strings and strings into uint8_t type variables, it should be noted that when uint8_t type variables are converted into strings, the corresponding characters of ASCII codes will be obtained. When strings are converted into uint8_t variables, the first character of the string will be assigned to variables.
For example, the following code:
- #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;
- }
The output of the above code is:
C
6
Self-understanding
- /* 7.18.1.1 Exact-width integer types */
- typedef signed char int8_t;
- typedef unsigned char uint8_t;
- typedef short int16_t;
- typedef unsigned short uint16_t;
- typedef int int32_t;
- typedef unsigned uint32_t;
- __MINGW_EXTENSION typedef long long int64_t;
- __MINGW_EXTENSION typedef unsigned long long uint64_t;
- /* 7.18.1.2 Minimum-width integer types */
- typedef signed char int_least8_t;
- typedef unsigned char uint_least8_t;
- typedef short int_least16_t;
- typedef unsigned short uint_least16_t;
- typedef int int_least32_t;
- typedef unsigned uint_least32_t;
- __MINGW_EXTENSION typedef long long int_least64_t;
- __MINGW_EXTENSION typedef unsigned long long uint_least64_t;
- /* 7.18.1.3 Fastest minimum-width integer types
- * Not actually guaranteed to be fastest for all purposes
- * Here we use the exact-width types for 8 and 16-bit ints.
- */
- typedef signed char int_fast8_t;
- typedef unsigned char uint_fast8_t;
- typedef short int_fast16_t;
- typedef unsigned short uint_fast16_t;
- typedef int int_fast32_t;
- typedef unsigned int uint_fast32_t;
- __MINGW_EXTENSION typedef long long int_fast64_t;
- __MINGW_EXTENSION typedef unsigned long long uint_fast64_t;
- /* 7.18.1.5 Greatest-width integer types */
- __MINGW_EXTENSION typedef long long intmax_t;
- __MINGW_EXTENSION typedef unsigned long long uintmax_t;