使用size_t变量时循环未结束

时间:2019-03-06 19:05:09

标签: c bit-manipulation size-t

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

我使用此“ for”指令检查来自无符号长长“映射”的位,但是当t变量变为1时,j在7(1 * 8 -1)和0((1-1)* 8),即使条件为jj >= (t - 1) * sizeof(unsigned long long)也会获得-1,-2,-3,-4和-5值,这对于'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
}

3 个答案:

答案 0 :(得分:3)

您正在遭受无符号整数环绕。

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

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

最好的解决方案是使用签名类型。除非t可能比SIZE_MAX/sizeof(long long)

大,否则您可能不需要size_t的所有位。

您说t在1到8之间。sizeof(unsigned long long)几乎可以肯定不超过16。因此j的可能范围是0..128。您可以毫无问题地将其放入常规的带符号的int(甚至带符号的char)中。

答案 1 :(得分:3)

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

@current_user

这样,您可以避免包含class Airport < ApplicationRecord has_many :preferences end @current_user.aiports.joins(:preferences).order(preferences: {created_at: :asc}) 的表达式,同时确保循环变量永不超出范围(即使初始值为零) ...)

答案 2 :(得分:0)

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

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

应该是

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

如果要使用signed版本,可以使用ssize_t,它可以表示数字-1,并且可以由函数返回以指示错误。

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