size_t数据类型的意义
1 int
的各种类型和size_t
类型
数据类型特别是int
相关的类型(int
,long
, long long
)在不同位数系统下长度不同,如下所示,特别是long
数据类型,在不同平台下字节数就不一样,为了保证平台的通用性,程序中尽量不要使用long
数据类型。
//32位系统
char 1个字节8位
short 2个字节16位
int 4个字节32位
long 4个字节
long long 8个字节
指针 4个字节
//64位系统
char 1个字节
short 2个字节
int 4个字节
long 8个字节(区别)
long long 8个字节
指针 8个字节(区别)
size_t
的诞生是为了让程序具有可移植性,size_t
是一些C/C++
标准在stddef.h
中定义的,它的真实类型与操作系统有关。
//在32位操作系统中被普遍定义为:
typedef unsigned int size_t; //4个字节
//在64位操作系统中被定义为:
typedef unsigned long size_t; //8个字节
而int
在不同的操作系统上都是4个字节,与size_t
不同,且int
是带符号的,size_t
是无符号的。
2 size_t类型的意义
size_t
类型是无符号的,但size_t
和unsigned int
又有所不同,size_t
的取值范围是目标平台下最大可能的数组尺寸,一些平台下的size_t
范围小于int
的正数范围,又或者大于unsigned int
。比如在64位下,int
是4个字节,但是size_t
是8个字节,这就意味着在64位下最大可能开辟的数组尺寸是2^64,如果使用int
作为数组的尺寸标记,那么就会失去 2^ 32 尺寸的数组机会。但是你会说谁会在64位系统上开辟一个大于2^32大小的连续数组呢?不不不,size_t
数据类型的意义并不在于此。
举个例子:在标准的C库中的许多函数使用的参数或者返回值都是表示的用字节表示的对象大小,如下:
// 按字节拷贝,从s2拷贝n个字节到s1地址
void *memcpy( void *s1 , const void *s2 , size_t n)
第三个参数数据类型如果改成int
可以吗?在大部分情况下是可以的,但并不是所有情况都可以。
int
是有符号的,它可以表示负数,但是大小只能是大于等于0,所以我们用unsigned int
类型来代替int
类型,会让第三个参数表示的范围更大。在大部分机器上,unsigned int
类型的最大值是int
类型的最大值的两倍,比如,在16位机器上,unsigned int
的最大值为65535,int
的最大值为32767。
void *memcpy( void *s1 , const void *s2 , unsigned int n)
若第三个参数采用unsigned int
类型,在16-bit 长整形
和指针类型32-bits
的平台上就不够用了,比如说摩托罗拉第一代处理器68000,在这种情况下,处理器可能拷贝的数据大于65535个字节,但是这个函数第三个参数n
不能处理这么大的数据。
若第三个参数采用unsigned long
类型呢?
void *memcpy(void *s1, void const *s2, unsigned long n);
显然,该类型可以处理更大的数据,移植性要比unsigned int
类型好很多,但是性能呢?比如在16位平台上,相较于unsigned int
类型来说,使用unsigned long
类型会使你的代码运行效率大打折扣(因为代码量变大导致运行变慢)。
使用size_t可以有效避免这种情况。size_t类型是一个类型定义,通常将一些无符号的整形定义为size_t,比如说nsigned int
或者unsigned long
,甚至unsigned long long
。
每一个标准C实现应该选择足够大的无符号整形来代表该平台上最大可能出现的对象大小,因此使用size_t
来代替int
或unsigned
可以保证在同一个平台中,始终得到一个数据类型或变量的字节大小,保证了程序对该数据类型或变量的统计方式始终一致,不会因为平台的改变而出现错误。
3 总结
-
使用size_t可能会提高代码的可移植性(不会因为平台的改变出现错误,因此对于无符号的整型数据,尽可能使用 size_t,而不是 int 或 unsigned)
-
使用size_t可能会提高代码的可读性(看到一个变量申请为size_t类型,你就知道它代表字节大小或数组索引,而不是错误代码或者使一个普通的值)
-
使用size_t可能会提高代码的程序效率(在16位系统上申请
unsigned long
数据类型需要两条机器指令去执行,大大降低了效率)
4 参考
size_t数据类型的意义