【问题标题】:Can I just use unsigned int instead of size_t? [duplicate]我可以只使用 unsigned int 而不是 size_t 吗? [复制]
【发布时间】:2021-06-13 21:52:52
【问题描述】:

我的印象是size_t 是unsigned int。但是我可以在我的代码中只写unsigned int 而不是size_t 吗?

【问题讨论】:

  • 这在很多系统上显然是错误的。例如在我的电脑上,unsigned int 是 32 位,size_t 是 64 位。
  • 请始终使用您所询问的编程语言标记您的问题。我已经添加了c 标签,但是如果您实际上是在询问 C++ 或其他内容,请相应地编辑标签。
  • @NateEldredge 这是我要同时添加 C 和 C++ 的一种情况
  • C++ std::size_t 在 <cstddef>、<cstdio>、<cstdlib>、<cstring>、<ctime>、<cuchar> 或 <cwchar> 中定义。它实际上是using size_t = decltype(sizeof 0);。它可能与(我不确定这是否详尽)相同:unsigned int、unsigned long 或 unsigned long long,具体取决于您的平台。
  • @Casey 这是错误的,当已经存在一种或另一种语言的答案时,您不应该添加或更改语言标签。对于如何交叉标记 C 和 C++ 问题,我们也有明确的规则。经验法则是,如果一个问题不包含任何 C++ 痕迹,也没有任何关于使用 C++ 编译器编译的评论,它不应该有 C++ 标签。阅读 C 和 C++ 标签 wiki 了解详细信息。我会回滚。

标签: c unsigned size-t


【解决方案1】:

size_t 是描述数组和对象大小时最正确的类型。它保证是无符号的,并且应该“足够大”以容纳给定系统的任何对象大小。因此,它比 unsigned int 更便于移植,在所有普通计算机上实际上都是 16 位或 32 位。

因此,在遍历数组时,for 循环的最规范形式实际上是:

for(size_t i=0; i<sizeof array/sizeof *array; i++)
{
  do_something(array[i]);
}

而不是int i=0;,即使在某些 C 书籍中也可能更常见。

size_t 也是sizeof 运算符返回的类型。在某些情况下使用正确的类型可能很重要,例如printf("%u", sizeof obj); 是形式上未定义的行为,因此理论上它可能会导致 printf 崩溃或打印乱码。 size_t 必须使用 %zu。

很可能size_t 恰好与unsigned long 或unsigned long long 或uint32_t 或uint64_t 是同一类型。

【讨论】:

  • @JDługosz 当我回答问题时,这最初被标记为 C。如果从那以后这个问题被破坏了,那不是我的错。
  • @JDługosz 出于好奇,您为什么不编写像 C++ 中那样简单易读的循环?除非您干预数组索引,否则您不能真正越界访问该数组。对普通的旧数据类型使用迭代器也没有明显的好处。看,我们不能为了简单的代码而编写复杂的代码,或者为了将尽可能多的 C++11 后特性塞进同一个翻译单元......
  • 是的,我会尽可能写得简单易读。通常:for (auto&amp; x : array) do_something(x);。如果您出于某种(好的)原因需要下标,并且在您的项目中没有一个方便的好库(例如 for (auto i : iota(array.size())) ,请使用一种好的方法来获取数组边界,而不是一种讨厌的易碎方法。
  • @JDługosz 除了auto 是讨厌和脆弱的......因为它没有类型安全。如果您不小心将错误的类型传递给它,您的细微类型错误会在整个项目中传播得更远,您将无法再分辨出您的变量是什么类型,因此很难追踪此类错误。
  • 我发现正好相反。像通用一样编写代码可以在其他代码更改时自动适应,减少维护,防止在人们键入不太正确的类型时进行不必要的转换,并且如果我们想进一步概括代码,以后可以很容易地变成模板.我不知道你所说的“微妙的打字错误蔓延”是什么意思——它适用与给定的类型。如果你有一个警示故事,我想知道,并想知道发布它的好地方是什么。
【解决方案2】:

size_t 类型是一个无符号类型,能够表示sizeof 和_Alignof 运算符的所有可能结果。 见https://port70.net/~nsz/c/c11/n1570.html#6.5.3.4p5

unsigned int 是 ...int 的无符号变体,可以表示 0 到 65535 之间的整数。它可能能够表示更大的整数。 见https://port70.net/~nsz/c/c11/n1570.html#5.2.4.2.1

它们可能是也可能不是同一类型。在现代 64 位机器上它们不是。

【讨论】:

  • [0, 65535] 只是unsigned int 所需的最小范围。大多数现代系统都有更大的unsigned int
  • @phuclv,是的.. 我会澄清答案
  • C 标准并没有明确保证size_t 可以代表sizeof 的所有可能结果,只是它是用于sizeof 结果的类型。正如123456*123456*123456 可以溢出int,sizeof(char [123456][123456][123456]) 可以溢出size_t(在数学意义上溢出,尽管C 对无符号类型进行了包装)。
  • @EricPostpischil,据我了解标准, sizeof 的结果是 size_t 类型。所以从技术上讲,溢出的是 sizeof 而不是 size_t。
猜你喜欢
  • 2013-10-20
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
  • 2021-10-17
相关资源
最近更新 更多