使用 size_t 变量时循环没有结束

Loop not ending when using a size_t variable

我使用了一个 size_t 变量来帮助我完成我的项目。但是,它不适用于我想要的所有情况,我真的不知道问题出在哪里。

我使用这个 'for' 指令来检查 unsigned long long "map" 中的位,但是当 t 变量变为 1,并且 j 是在 7 ( 1 * 8 - 1) 和 0 ( (1 - 1) * 8 ) 之间,j 也会得到 -1、-2、-3、-4 和 -5 值,即使条件是 j >= (t - 1) * sizeof(unsigned long long),'t = 1' 的情况是 j >= 0。我真的不知道为什么,对于 t = 1 的情况,我用 int 替换了 size_t,但我真的很想知道为什么会这样,我做错了什么以及如何解决它.

int t; //( it gets values between 8 and 1 )
...
for ( size_t j = t * sizeof(unsigned long long) - 1; 
      j >= (t - 1) * sizeof(unsigned long long); 
      j--) {
    map_mask = help64 << j;
    printf("%zd ",j); // that s how i figured out i get negative numbers
                      //checking bit by bit and return 0(not fitting) if we see any bit equal
    if ( (map_mask & (*map)) == map_mask ) {
        mask8 = help8 << k;
        if ( (mask8 & p) == mask8 )
            return 0;
    }
    k-- ;// a variable i used for the mask( i initiated it with k = 7, it doesnt matter here
}

类型 size_t 是无符号的,因此不应用作

printf("%zd ", j);      // signed version

应该是

printf("%zu ", j);      // unsigned version

如果您想要 signed 版本,您可以使用 ssize_t,它能够表示数字 -1,并且可以通过函数返回作为指示错误的一种方式。

在向下计数的循环中使用 unsigned 变量可能很危险。

您遇到无符号整数回绕问题。

for (unsigned j = 7; j>=0; j--)
{ //whatever 
}

所以当j为0时,进入循环,进行处理,然后自减。由于 j 是无符号的,它不会变成 -1,而是 0xFFFF.... ((1<<sizeof(size_t))-1),它非常大并且肯定大于 0。

最好的解决方案是使用签名类型。您可能不需要 size_t 的所有位,除非 t 可能大于 SIZE_MAX/sizeof(long long)

你说t在1到8之间。sizeof(unsigned long long)几乎可以肯定不超过16。所以j的可能范围是0..128。你可以把它放在一个普通的有符号整数中,(或者甚至是一个有符号的字符)没有问题。

使用无符号类型进行倒计时的最简洁模式是恕我直言:

size_t idx;
for(idx = xxx*CHAR_BIT; idx-- >0; ) {
    ...    
    }

这样可以避免包含 -1+1 的表达式,同时保证循环变量 never 永远不会越界(即使初始值为零...)