Цикл не заканчивается при использовании переменной size_t - PullRequest
0 голосов
/ 06 марта 2019

Я использовал переменную size_t, чтобы помочь мне сделать мой проект.Однако, это работает не во всех случаях, которые я хочу, и я действительно не знаю, в чем проблема.

Я использую эту инструкцию для проверки битов из длинной карты без знака long, но когда переменная 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 size_t на int, но мне бы очень хотелось знать, почему это происходит, что я делаю неправильно и как я могу это исправить.

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 ]

3 голосов
/ 06 марта 2019

Вы страдаете от целочисленного переноса без знака.

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.Вы можете поместить это в обычный подписанный int (или даже в char) без проблем.

3 голосов
/ 07 марта 2019

Самый чистый шаблон для обратного отсчета с использованием неподписанных типов: IMHO:

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

Таким образом вы избегаете выражений, содержащих -1 или +1, гарантируя, что переменная цикла будет никогда никогда не выходит за пределы (даже если начальное значение будет равно нулю ...)

0 голосов
/ 06 марта 2019

Тип size_t не подписан, поэтому его не следует использовать как

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

. Это должно быть

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

Если вы хотите версию signed, вы можете использоватьssize_t, который может представлять число -1 и может быть возвращен функциями как способ указать на ошибку.

Может быть опасно использовать переменную unsigned в цикле, который считает вниз.

...