Разве это плохо, чтобы переполнить и переполнить неподписанную переменную?

Kraaa.

Я учусь в школе программирования, которая требует, чтобы мы написали C-функции с менее чем 25 строками кода. Итак, в основном, каждая строка имеет значение. Иногда мне нужно укорачивать задания примерно так:

#include <stddef.h>
#include <stdio.h>

#define ARRAY_SIZE  3

int     main(void)
{
    int     nbr_array[ARRAY_SIZE] = { 1, 2, 3 };
    size_t  i;

    i = -1;
    while (++i < ARRAY_SIZE)
        printf("nbr_array[%zu] = %i\n", i, nbr_array[i]);
    return (0);
}

Важной частью этого кода является size_t счетчик имени i, Чтобы сэкономить несколько строк кода, я хотел бы предварительно увеличить его в условии цикла. Но, поскольку стандарт C определяет size_t как тип без знака, то, что я в основном делаю здесь i переменная (от 0 до очень большого значения), затем переполняет его один раз (от этого большого значения до 0).

Мой вопрос заключается в следующем: независимо от плохой практики сокращения нашего кода, безопасно ли устанавливать unsigned ( size_t ) переменная до -1, а затем предварительно увеличивать его на каждой итерации, чтобы просмотреть массив?

Спасибо!

3 ответа

Решение

i = -1; часть вашей программы в порядке.

преобразование -1 к целому типу без знака определяется в C и приводит к значению, которое, если увеличивается, приводит к нулю.

Тем не менее, вы не получаете никакой строки кода в отношении идиоматического for (i=0; i<ARRAY_SIZE; i++) …,

Ваш %zi формат должен быть наверное %zu,

Арифметика без знака никогда не "переполняется / переполняется" (по крайней мере в том смысле, в котором стандарт говорит о неопределенном поведении переполнения арифметики со знаком). Вся арифметика без знака на самом деле является модульной арифметикой и, как таковая, является безопасной (то есть она не будет вызывать неопределенное поведение само по себе).

Чтобы быть точным, стандарт C гарантирует две вещи:

  • Любое целочисленное преобразование в unsigned тип хорошо определен (как будто число со знаком было представлено как 2-дополнение)
  • переполнение / недостаток unsigned целые числа хорошо определены (модульная арифметика с 2^n)

поскольку size_t это неподписанный тип, вы не делаете ничего плохого.

Другие вопросы по тегам