目录
文章目录
- 目录
- size_t 的作用
- size_t 的使用
size_t 的作用
在 C 语言程序中使用 size_t(size_type)可以提高代码的可移植性、有效性、可读性。实际上,在 K&D C 中并没有提供 size_t 类型,而是 C 标准委员会为了解决程序的可移植性问题将 size_t 引入的。
在 C 标准库中,许多函数的参数或返回值都是用字节(Byte)来表示对象的大小。例如:
- malloc(n):n 指明了需要申请的内存大小。
- memcpy(s1, s2, n):n 表明了需要复制的内存大小。
- strlen(s):返回值为以 ‘\0’ 结尾的字符串的长度(不包括 ‘\0’)。
或许你会认为这些参数或返回值应该被声明为 int、long 或者 unsigned 类型,但实际上 C 标准将他们定义为 size_t 类型:
void *malloc(size_t n);
void *memcpy(void *s1, void const *s2, size_t n);
size_t strlen(char const *s);
为什么不使用 int 而是使用 size_t 类型呢?这是因为 int 类型一般小于等于数据线的宽度,而 size_t 类型一般为大于等于地址线宽度。而地址线宽度通常是大于数据线宽度的:在数据只有 8 位的年代,地址率先进入 10 位、12 位;在数据 16 位的年代,地址也已经进入了 20 位、24 位;后来 int 普遍是 32 位,而地址线宽度在主流平台中都是 64 位。
size_t 为什么存在?因为无论 int 还是 unsigned 都很可能小于地址线宽度需要的大小,所以必须有个 size_t。
简而言之,size_t 是一种无符号的整型(unsigned int、unsigned long、unsigned long long),是与平台无关的,取值范围是目标平台下最大可能的数组尺寸(0-MAXINT)。它的取值没有负数(在数组中也用不到负数),而它的取值范围是整型数的双倍。sizeof 关键字的返回类型就是 size_t。
参数中带有 size_t 的函数通常会含有局部变量用来对数组的大小或者索引进行计算,在这种情况下,size_t 是个不错的选择。适当地使用 size_t 还会使你的代码变得更加可读。当你看到一个对象声明为 size_t 类型时,你马上就知道它代表字节大小或数组索引,而不是错误代码或者是一个普通的算术值。
为什么命名为 size_t 呢?_t 的意思就是 type。一个类型后面加了 _t 表面这是一个 POSIX 或 GNU 的保留类型,防止命名空间污染(Namespace Pollution)。POSIX 规定 C 语言自身扩展的类型都有 _t 后缀,这样就不会与用户自定义的类型的命名冲突了。
size_t 的使用
size_t 的定义在 stddef.h、stdio.h、stdlib.h、string.h、time.h 和 wchar.h 这些标准 C 的头文件中,包含以上任一头文件,则表明 size_t 将作为一个全局关键字。
根据定义,sizeof() 的返回值就是一个 size_t 类型:
n = sizeof(thing);