我是C的新手,最近因数据类型和内存分配不匹配而遇到了一些麻烦。我正在编写一个非常简单的程序来计算使用Linux系统调用读取的文件的xor校验和。
我的问题是:在将 off_t 或 ssize_t 与长或 INT
例如:
long i;
for(i = 0; i < fileStat.st_size; i++)
{
// do stuff
}
还有:
ssize_t i;
for(i = 0; i < fileStat.st_size; i++)
{
// do stuff
}
答案 0 :(得分:3)
比较相同签名但不同大小的类型相互作用,因为较小的类型扩展为较大的类型。比较不同签名的类型是有问题的,因为如果签名类型不大于无符号类型且签名数字为负,则可能会得到错误的结果。最好确保签名号码最初不是负数:
signed_t a;
unsigned_t b;
/* instead of */
if (a < b)
/* ... */
/* use */
if (a < 0 || a < b)
/* ... */
答案 1 :(得分:1)
C标准规定long
类型足以表示常量LONG_MAX
,其必须至少为2147483647(2 31 -1)。如果我们将此下限作为LONG_MAX
的值,那么它可能不够大。毕竟,它不到2 GiB。
ssize_t
不在C标准中,但在POSIX标准中定义。它必须足够大以表示常量SSIZE_MAX
,其必须至少为32767(2 15 -1)。也不要依赖这种类型。
在我的计算机上,long
和ssize_t
都是4个字节。您可以使用sizeof
运算符自行验证尺寸。您可能会得到不同的结果。如果您希望程序可移植,请不要依赖于特定于实现的程序。
最后,如果您真的不想使用这些typedef,我建议使用unsigned long long
类型。它足以表示常量ULLONG_MAX
,必须至少为18446744073709551615(2 64 -1)。
另请参阅:http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html
答案 2 :(得分:0)
有关有符号整数和无符号整数(以及其他算术运算)之间比较的警告源于两个不同类型的操作数与运算符组合时发生的隐式转换。
Gimpel的PC-Lint工具随附的手册中有一个很好的章节。
特别阅读可用的C标准文件&#34;整数促销&#34;很有帮助。
例如在http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf(C99) - 第6.3.1节&#34;算术操作数&#34;
特别是&#34;如果int可以表示原始类型的所有值,则该值将转换为int;否则,它将转换为unsigned int&#34;
因此,在这样的背景下,&#34; -1&#34;将被转换为二进制all-one [依赖于实现]作为无符号数字 - 可能会给那些粗心大意的人带来惊人的结果。例如,无符号整数除以整数&#34; -1&#34;将给予零。
答案是在算术之前将无符号转换为带符号的值。
请注意,sizeof()返回无符号值。