uint32_t与int区别与联系

1.背景介绍

在一些程序中经常看到uint8_t uint32_t等数据类型,那么它与我们常见的int类型有什么区别呢。

2.协议介绍

stdint.h头文件是为了代码的可移植性而推出的,C99中就已经规范了。

3.代码可移植性

3.1 数据类型的差异

大部分的32位系统采用的是ILP32(这个对于嵌入式是在ABI文档中规定的ARM的ABI文档),大部分64位系统采用的是LP64。各个系统基本数据类型长度对比如图所示:

TYPEILP32LP64LLP64LP332ILP64
char11111
short22222
int44428
long48448
long long88888
float44444
double88888
size_t48848
pointer48848

3.2 ILP32 与LP64的对比

TypeILP32 sizeofILP32 printLP64 sizeofLP64 print备注
bool1%u1%uC++
char1%d或%c1%d或%c
unsigned char1%u1%u
short2%d2%d
unsigned short2%u2%u
int4%d4%d
unsigned int4%u4%u
long4%ld8%ld有差异
unsigned long4%lu8%lu有差异
long int4%ld8%ld有差异
unsigned long int4%lu8%lu有差异
long long8%lld8%lld
unsigned long long8%llu8%llu
type *4%p8%p有差异
pid_t4%d4%d
socklen_t4%u4%u
off_t4%zd8%zd有差异
time_t4%zd8%zd有差异
pthread_t4%zu8%zu有差异
size_t4%zu8%zu有差异
ssize_t4%zd8%zd有差异

基于可移植性要求,在32位和64位条件下,可变长度的数据类型可能导致兼容性错误

3.3 数据类型统一化

类型定义ILP32LP64PRINT使用场景及代替类型
void---void,无类型,仅用于占位和通用指针定义
char11%c对于字符串、数组直接使用原生char
int8_t11%d对于1字节整型使用int8_t,uint8_t
uint8_t11%u对于1字节整型使用int8_t,uint8_t
int16_t22%d代替short
uint16_t22%u代替unsigned short
int32_t44%d代替int
uint32_t44%u代替unsigned int
int64_t88%PRId64代替long long、宏实现代码兼容
uint64_t88%PRIu64代替unsigned long long、宏实现代码兼容
float44%f单精度浮点数
double88%lf双精度浮点数
bool11%d布尔类型
uintptr_t48%zu会根据32位和64位的不同定义为不同的长度,用于可能存储指针的场景
type *48%ptype *,可变长度类型,与uintptr_t等价,存在类型转换时建议使用uintptr_t
nullptr_t48%p指针初始化
pid_t44%dLinux内置,固定长度
socklen_t44%uLinux内置,固定长度
off_t/time_t48%zd可变长度类型,有符号
size_t/pthread_t48%zu可变长度类型,无符号,仅用于调用库函数的兼容性要求(比如底层API中使用了size_t)

4.代码实践

4.1 代码示例

在线编译环境:https://godbolt.org/ X86-64 gcc 9.4

#include <stdio.h>
#include <stdint.h>
int32_t main()
{  
    printf("int: %d\n",sizeof(int));
    printf("long:%d\n",sizeof(long));
    printf("uint32_t:%d\n",sizeof(uint32_t));
    printf("uint64_t:%d\n",sizeof(uint64_t));
}
int: 4
long:8
uint32_t:4
uint64_t:8

4.1 stdint.h

以下为从gcc编译链提取的stdint头文件,x86_64 x86_64 GNU/Linux

#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也是对int等不同的类型的重定义而已,只是实现了跨平台;

5.参考文献

1.ISO/IEC 9899 :TC3
2.鸿蒙代码移植规范

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值