目录

文章目录

size_t 的作用

在 C 语言程序中使用 size_t(size_type)可以提高代码的可移植性、有效性、可读性。实际上,在 K&D C 中并没有提供 size_t 类型,而是 C 标准委员会为了解决程序的可移植性问题将 size_t 引入的。

size_t 的定义在 stddef.h、stdio.h、stdlib.h、string.h、time.h 和 wchar.h 这些标准 C 的头文件中,包含以上任一头文件,则表明 size_t 将作为一个全局关键字。

  • 在 32 位架构中被普遍定义为:
typedef unsigned int size_t;
  • 在 64 位架构中被定义为:
typedef unsigned long size_t;

从定义可以看出,size_t 是一种无符号的整型(unsigned int、unsigned long、unsigned long long),取值范围是目标平台下最大的可能范围。sizeof 关键字的返回类型就是 size_t。

#include <stdio.h>

int main() {
    printf("Int size: %d", sizeof(int));
}

// Int size: 4

上述例子表示 int 类型在当前的操作系统中具有 4 个字节的大小。

为什么不直接使用 int 而是使用 size_t 类型来标识字节大小呢?这是因为 int 类型一般小于等于数据线的宽度,而 size_t 类型一般为大于等于地址线宽度,地址线宽度通常是大于数据线宽度的。在数据只有 8 位的年代,地址率先进入 10 位、12 位;在数据 16 位的年代,地址也已经进入了 20 位、24 位;后来 int 普遍是 32 位,而地址线宽度在主流平台中都是 64 位。所以,无论 int 还是 unsigned 都很可能小于地址线宽度需要的大小,进而就必须有个 size_t。

使用 size_t 来代替 int 或 unsigned 可以保证在同一个平台中,始终得到得到一个数据类型或变量的字节大小,保证了程序对该数据类型或变量的统计方式始终一致,不会因为平台的改变而出现错误

C 的标准函数中大量使用到了 size_t 类型来表示取值的字节数:

void *malloc(size_t size);
void *memcpy(void *s1, void const *s2, size_t size);
size_t strlen(char const *s);

形式参数中带有 size_t 的函数通常会含有局部变量用来对数组的大小或者索引进行计算,在这种情况下,size_t 是个不错的选择,因为数组索引和 size_t 都没有负数。适当地使用 size_t 会使你的代码变得更加可读,当你看到一个对象声明为 size_t 类型时,你马上就知道它用于代表字节大小及数量,或者表示数组索引,而不是一个普通的算术值。

for(size_t i=0; i<300; i++) {}

为什么命名为 size_t 呢?_t 的意思就是 type。一个类型后面加了 _t 表面这是一个 POSIX 或 GNU 的保留类型,防止命名空间污染(Namespace Pollution)。POSIX 规定 C 语言自身扩展的类型都有 _t 后缀,这样就不会与用户自定义的类型的命名冲突了。

为了使程序具有很好的移植性,C/C++ 程序员应该尽量使用 size_t,而不是 int 或 unsigned