c/c++: uint8_t uint16_t uint32_t uint64_t size_t ssize_t数据类型

本文解释了C语言中以_t结尾的数据类型含义,例如uint8_t等,并详细介绍了这些类型如何通过typedef定义以及它们在不同平台上的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在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

附:inttypes.h的内容(不同的服务器会有不同的源文件结构,但原理是一样的,我这里sun服务器inttypes.h引用了int_type.h)

  1. bash-3.00$ vi int_types.h   
  2. "int_types.h" [Read only] 176 lines, 4367 characters   
  3. /* 
  4.  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved. 
  5.  * Use is subject to license terms. 
  6.  */  
  7.   
  8. #ifndef _SYS_INT_TYPES_H  
  9. #define _SYS_INT_TYPES_H  
  10.   
  11. #pragma ident   "@(#)int_types.h        1.10    04/09/28 SMI"  
  12.   
  13. /* 
  14.  * This file, <sys/int_types.h>, is part of the Sun Microsystems implementation 
  15.  * of <inttypes.h> defined in the ISO C standard, ISO/IEC 9899:1999 
  16.  * Programming language - C. 
  17.  * 
  18.  * Programs/Modules should not directly include this file.  Access to the 
  19.  * types defined in this file should be through the inclusion of one of the 
  20.  * following files: 
  21.  * 
  22.  *      <sys/types.h>           Provides only the "_t" types defined in this 
  23.  *                              file which is a subset of the contents of 
  24.  *                              <inttypes.h>.  (This can be appropriate for 
  25.  *                              all programs/modules except those claiming 
  26.  *                              ANSI-C conformance.) 
  27.  * 
  28.  *      <sys/inttypes.h>        Provides the Kernel and Driver appropriate 
  29.  *                              components of <inttypes.h>. 
  30.  * 
  31.  *      <inttypes.h>            For use by applications. 
  32.  * 
  33.  * See these files for more details. 
  34.  */  
  35.   
  36. #include <sys/feature_tests.h>  
  37.   
  38. #ifdef __cplusplus  
  39. extern "C" {  
  40. #endif  
  41.   
  42. /* 
  43.  * Basic / Extended integer types 
  44.  * 
  45.  * The following defines the basic fixed-size integer types. 
  46.  * 
  47.  * Implementations are free to typedef them to Standard C integer types or 
  48.  * extensions that they support. If an implementation does not support one 
  49.  * of the particular integer data types below, then it should not define the 
  50.  * typedefs and macros corresponding to that data type.  Note that int8_t 
  51.  * is not defined in -Xs mode on ISAs for which the ABI specifies "char" 
  52.  * as an unsigned entity because there is no way to define an eight bit 
  53.  * signed integral. 
  54.  */  
  55. #if defined(_CHAR_IS_SIGNED)  
  56. typedef char                    int8_t;  
  57. #else  
  58. #if defined(__STDC__)  
  59. typedef signed char             int8_t;  
  60. #endif  
  61. #endif  
  62. typedef short                   int16_t;  
  63. typedef int                     int32_t;  
  64. #ifdef  _LP64  
  65. #define _INT64_TYPE  
  66. typedef long                    int64_t;  
  67. #else   /* _ILP32 */  
  68. #if defined(_LONGLONG_TYPE)  
  69. #define _INT64_TYPE  
  70. typedef long long               int64_t;  
  71. #endif  
  72. #endif  
  73.   
  74. typedef unsigned char           uint8_t;  
  75. typedef unsigned short          uint16_t;  
  76. typedef unsigned int            uint32_t;  
  77. #ifdef  _LP64  
  78. typedef unsigned long           uint64_t;  
  79. #else   /* _ILP32 */  
  80. #if defined(_LONGLONG_TYPE)  
  81. typedef unsigned long long      uint64_t;  
  82. #endif  
  83. #endif  
  84.   
  85. /* 
  86.  * intmax_t and uintmax_t are to be the longest (in number of bits) signed 
  87.  * and unsigned integer types supported by the implementation. 
  88.  */  
  89. #if defined(_INT64_TYPE)  
  90. typedef int64_t                 intmax_t;  
  91. typedef uint64_t                uintmax_t;  
  92. #else  
  93. typedef int32_t                 intmax_t;  
  94. typedef uint32_t                uintmax_t;  
  95. #endif  
  96.   
  97. /* 
  98.  * intptr_t and uintptr_t are signed and unsigned integer types large enough 
  99.  * to hold any data pointer; that is, data pointers can be assigned into or 
  100.  * from these integer types without losing precision. 
  101.  */  
  102. #if defined(_LP64) || defined(_I32LPx)  
  103. typedef long                    intptr_t;  
  104. typedef unsigned long           uintptr_t;  
  105. #else  
  106. typedef int                     intptr_t;  
  107. typedef unsigned int            uintptr_t;  
  108. #endif  
  109.   
  110. /* 
  111.  * The following define the fastest integer types that can hold the 
  112.  * specified number of bits. 
  113.  */  
  114. #if defined(_CHAR_IS_SIGNED)  
  115. typedef char                    int_fast8_t;  
  116. #else  
  117. #if defined(__STDC__)  
  118. typedef signed char             int_fast8_t;  
  119. #endif  
  120. #endif  
  121. typedef int                     int_fast16_t;  
  122. typedef int                     int_fast32_t;  
  123. #ifdef  _LP64  
  124. typedef long                    int_fast64_t;  
  125. #else   /* _ILP32 */  
  126. #if defined(_LONGLONG_TYPE)  
  127. typedef long long               int_fast64_t;  
  128. #endif  
  129. #endif  
  130.   
  131. typedef unsigned char           uint_fast8_t;  
  132. typedef unsigned int            uint_fast16_t;  
  133. typedef unsigned int            uint_fast32_t;  
  134. #ifdef  _LP64  
  135. typedef unsigned long           uint_fast64_t;  
  136. #else   /* _ILP32 */  
  137. #if defined(_LONGLONG_TYPE)  
  138. typedef unsigned long long      uint_fast64_t;  
  139. #endif  
  140. #endif  
  141.   
  142. /* 
  143.  * The following define the smallest integer types that can hold the 
  144.  * specified number of bits. 
  145.  */  
  146. #if defined(_CHAR_IS_SIGNED)  
  147. typedef char                    int_least8_t;  
  148. #else  
  149. #if defined(__STDC__)  
  150. typedef signed char             int_least8_t;  
  151. #endif  
  152. #endif  
  153. typedef short                   int_least16_t;  
  154. typedef int                     int_least32_t;  
  155. #ifdef  _LP64  
  156. typedef long                    int_least64_t;  
  157. #else   /* _ILP32 */  
  158. #if defined(_LONGLONG_TYPE)  
  159. typedef long long               int_least64_t;  
  160. #endif  
  161. #endif  
  162.   
  163. typedef unsigned char           uint_least8_t;  
  164. typedef unsigned short          uint_least16_t;  
  165. typedef unsigned int            uint_least32_t;  
  166. #ifdef  _LP64  
  167. typedef unsigned long           uint_least64_t;  
  168. #else   /* _ILP32 */  
  169. #if defined(_LONGLONG_TYPE)  
  170. typedef unsigned long long      uint_least64_t;  
  171. #endif  
  172. #endif  
  173.   
  174. #ifdef __cplusplus  
  175. }  
  176. #endif  
  177.   
  178. #endif /* _SYS_INT_TYPES_H */  

同理在types.h文件中会有size_t ssize_t的定义,篇幅较长不贴出了。

<think>回调(Callback)是一种编程机制,它允许将一个函数(称为回调函数)作为参数传递给另一个函数,并在特定事件或条件发生时被调用。在C语言中,回调通常通过函数指针实现。 ### 回调的详细解释 1. **基本概念**: - 回调函数不是由实现方直接调用,而是传递给另一个函数(或模块),由接收方在适当的时机调用。 - 常用于事件处理、异步操作、自定义行为注入等场景。 2. **C语言中的实现**: ```c // 定义回调函数类型 typedef void (*CallbackFunc)(int event_id, void* user_data); // 注册回调的函数 void register_callback(CallbackFunc cb, void* user_data) { // 模拟事件发生 int event_id = 100; cb(event_id, user_data); // 调用回调 } // 实际回调函数 void my_callback(int event_id, void* user_data) { printf("Event %d occurred\n", event_id); } int main() { register_callback(my_callback, NULL); return 0; } ``` 3. **在UBUS中的应用**: - 如`ubus_handler_t`是方法调用的回调类型: ```c typedef int (*ubus_handler_t)(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg); ``` - 当收到对某方法的调用请求时,UBUS框架会执行对应的回调函数。 --- ### C语言标准类型解析 #### `size_t` | 特性 | 说明 | |------|------| | **定义** | `typedef unsigned int size_t;` (实际取决于平台) | | **头文件** | `<stddef.h>` 或 `<stdlib.h>` | | **用途** | 表示内存中对象的大小(如`sizeof`运算符的返回类型) | | **位宽** | 通常与指针宽度一致(32位系统为32位,64位系统为64位) | | **示例** | `malloc(size_t size)`, `strlen`返回类型 | #### `uint32_t` | 特性 | 说明 | |------|------| | **定义** | `typedef unsigned int uint32_t;` (精确32位) | | **头文件** | `<stdint.h>` | | **用途** | 明确表示32位无符号整数 | | **位宽** | 固定32位(跨平台保证) | | **示例** | 网络协议、硬件寄存器操作 | #### 其他类似类型 | 类型 | 等价含义 | 说明 | |------|----------|------| | `int8_t` | 8位有符号整数 | 范围:-128~127 | | `uint64_t` | 64位无符号整数 | 范围:0~18,446,744,073,709,551,615 | | `ssize_t` | 有符号的`size_t` | 用于可能返回负值的场景(如错误码) | --- ### 类型使用示例 ```c #include <stdint.h> #include <stdio.h> int main() { size_t file_size = 1024 * 1024; // 1MB uint32_t pixel_color = 0xFF00FF; // ARGB颜色值 printf("File size: %zu bytes\n", file_size); // %zu用于size_t printf("Color code: 0x%06X\n", pixel_color); return 0; } ``` §§相关问题§§ 1. 在C语言中,回调函数使用`void* user_data`参数的目的是什么? 2. `size_t`和`uintptr_t`有何区别?各自应在什么场景下使用? 3. 为什么网络编程和嵌入式系统中推荐使用`uint32_t`而非`unsigned int`? 4. 如何设计一个支持多级嵌套回调的系统(如事件链)?</think>### 深入解析:回调机制与C语言标准类型 #### 一、**回调(Callback)机制详解** 回调是编程中的核心概念,本质是**函数指针的进阶应用**,其工作原理如下: ```c // 1. 定义回调函数类型 typedef void (*EventCallback)(int event_id, void *user_data); // 2. 接收回调的函数 void register_event_handler(EventCallback cb, void *user_data) { // 当事件发生时... int current_event = 1001; cb(current_event, user_data); // 执行回调 } // 3. 实际回调函数实现 void my_event_handler(int event_id, void *user_data) { printf("处理事件 %d (用户数据: %p)\n", event_id, user_data); } int main() { int user_value = 42; register_event_handler(my_event_handler, &user_value); } ``` ##### 关键特征: 1. **逆向调用**:由被调用方(如库/框架)在特定条件下触发调用方的函数 2. **解耦设计**:调用方无需知道被调用方的具体实现 3. **应用场景**: - 事件驱动系统(如UBUS的事件通知) - 异步操作完成通知 - 自定义算法策略注入 #### 二、**C语言标准类型深度解析** | 类型 | 头文件 | 位数 | 表示范围 | 典型应用场景 | |------|--------|------|----------|-------------| | **`size_t`** | `<stddef.h>` | 平台相关<br>(32:4B, 64位:8B) | 足够表示任何对象大小 | `sizeof`返回值<br>内存分配函数<br>`strlen`返回值 | | **`uint32_t`** | `<stdint.h>` | 固定32位 | 0 ~ 4,294,967,295 | 网络协议字段<br>硬件寄存器<br>跨平台数据交换 | | **`int32_t`** | `<stdint.h>` | 固定32位 | -2,147,483,648 ~ 2,147,483,647 | 有符号整型运算 | | **`uint64_t`** | `<stdint.h>` | 固定64位 | 0 ~ 18,446,744,073,709,551,615 | 大文件操作<br>高精度时间戳 | | **`ssize_t`** | `<sys/types.h>` | 同`size_t` | -最大值 ~ 最大值-1 | 可能返回负值的系统调用<br>(如`read()`错误时返回-1) | ##### 类型选择原则: 1. **精确控制**:`uint32_t`保证4字节,避免`unsigned int`的跨平台差异 2. **内存敏感**:嵌入式系统优先使用`uint8_t`/`uint16_t` 3. **平台适配**: ```c #if __SIZEOF_POINTER__ == 8 typedef uint64_t ptr_val; #else typedef uint32_t ptr_val; #endif ``` #### 三、**UBUS中的回调应用实例** ```c // UBUS方法回调定义 typedef int (*ubus_handler_t)( struct ubus_context *ctx, // UBUS上下文 struct ubus_object *obj, // 目标对象 struct ubus_request_data *req, // 请求元数据 const char *method, // 方法名 struct blob_attr *msg // 二进制消息数据 ); // 注册回调到对象 struct ubus_object my_obj = { .name = "custom.service", .methods = (struct ubus_method[]){ { .name = "restart", .handler = restart_handler }, { .name = "status", .handler = status_handler } }, .n_methods = 2 }; ``` 当调用`ubus call custom.service restart`时,UBUS核心将定位并执行`restart_handler`回调函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值