C89: несоответствие со знаком/неподписанное

Обязательно плохи несоответствия со знаком/неподписанные?

Вот моя программа:

int main(int argc, char *argv[]) {
    unsigned int i;

    for (i = 1; i < argc; i++) { // signed/unsigned mismatch here

    }
}

argc подписывается, i не. Действительно ли это - проблема?

5
задан Nick Heiner 14 February 2010 в 20:56
поделиться

4 ответа

"Несовпадения подписи/неподписи" могут быть плохими. В своем вопросе вы спрашиваете о сравнении. При сравнении двух значений одного базового типа, но одного знакового и одного беззнакового, знаковое значение преобразуется в беззнаковое. Таким образом,

int i = -1;
unsigned int j = 10;

if (i < j)
    printf("1\n");
else
    printf("2\n");

выводит 2, а не 1. Это происходит потому, что в i < j, i преобразуется в unsigned int. (unsigned int)-1 равно UINT_MAX, очень большому числу. Таким образом, условие оценивается как false, и вы переходите к пункту else.

Для вашего конкретного примера argc гарантированно неотрицателен, поэтому вам не нужно беспокоиться о "несоответствии".

9
ответ дан 13 December 2019 в 05:34
поделиться

Я предполагаю, что вы ищете что-то похожее на то, как обычно работает BASIC (загрузитесь до подсказки BASIC и начните кодирование).

IPython позволяет делать это достаточно интуитивно. Оболочки Unix, такие как Bash, используют ту же концепцию, но вы не можете повторно использовать и сохранить свою работу почти так же интуитивно, как с IPython. Python также гораздо лучше язык общего назначения.

Изменить: Я собирался ввести некоторые примеры и предоставить некоторые ссылки, но IPython интерактивный учебник , кажется, делает это намного лучше, чем я мог. Хорошими отправными точками для того, что вы ищете, являются разделы советов по обработке исходного кода и облегченного управления версиями . Обратите внимание, что в этом учебном пособии не описано, как сделать все, что вы ищете точно, но в нем предусмотрена точка перехода, чтобы понять интерактивные возможности оболочки IPython.

Также взгляните на «магическую» ссылку IPython , поскольку она предоставляет множество утилит, которые делают вещи, специфичные для того, что вы хотите сделать, и позволяет вам легко определить свои собственные. Это очень «мета», но пример, показывающий, как создать магическую функцию IPython, вероятно, самый лаконичный пример «полного приложения», построенного в IPython.

-121--4538115-

Не перемещайте оставшееся содержимое изделия; он ничего не делает. Вместо этого возьмите предметы, которые вы хотите уплыть вправо, и поместите их над основным содержимым. Так работают поплавки. Если вы обнаружите, что он не работает, даже после тестирования, повторите попытку: P

-121--4631692-

Неплохо. Я бы исправил предупреждения компилятора о несоответствии подписанных/неподписанных, потому что плохие вещи могут случиться, даже если они маловероятны или невозможны. Когда вы должны исправить ошибку из-за несоответствия подписанных/неподписанных, компилятор в основном говорит «Я сказал вам так». Не игнорируйте предупреждение по какой-то причине.

1
ответ дан 13 December 2019 в 05:34
поделиться

Это не является реальной проблемой в вашем конкретном случае, но компилятор не может знать, что argc всегда будет иметь значения, которые не вызовут никаких проблем.

1
ответ дан 13 December 2019 в 05:34
поделиться

Это лишь косвенная проблема.

Плохие вещи могут случиться, если вы используете целые числа со знаком для побитовых операций, таких как & , | , << и >> .
Совершенно разные неприятности могут случиться, если вы используете целые числа без знака для арифметики (потеря значимости, бесконечные циклы при проверке, является ли число > = 0 и т. Д.)

Из-за этого , некоторые компиляторы и инструменты статической проверки будут выдавать предупреждения, когда вы смешиваете знаковые и беззнаковые целые числа в любом типе операции (арифметические или битовые манипуляции).

Хотя их можно безопасно смешивать в простых случаях, таких как ваш пример, если вы это сделаете это означает, что вы не можете использовать эти инструменты статической проверки (или должны отключить эти предупреждения), что может означать, что другие ошибки останутся незамеченными.

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

В вашем примере я бы придерживался int просто потому, что проще иметь меньше типов, а int все равно будет там, поскольку это тип первый аргумент функции main () .

1
ответ дан 13 December 2019 в 05:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: