2015-09-13 5 views
-2

Я пытаюсь напечатать значение особо большого значения после прочтения его с консоли. Когда я пытаюсь распечатать его двумя разными способами: один сразу после назначения, один с возвращаемым значением из функции strtol, я получаю другой вывод! Может кто-нибудь, пожалуйста, объясните мне, почему я замечаю два разных результата?Различные выходные данные с печатью

Вводимое значение: 4294967290

Вот фрагмент кода.

long int test2 = strtol(argv[1], &string, 10); 
printf("the strtol value is %ld\n", test2); 
printf("the strtol function value is %ld\n", strtol(argv[1], &string, 10)); 

Выход

the strtol value is -6 
the strtol function value is 4294967290 
+0

«PS: Отправьте мне запрос, если этот вопрос уже был дан. Спасибо!» Это исследование, которое вы уже должны были сделать, прежде чем вы разместили вопрос –

+0

Опубликованный код выглядит нормально для меня. –

+2

Мне то же самое.Я думаю, что проблема в других частях – BLUEPIXY

ответ

2

Вы должны сделать две вещи:

  1. Добавьте строку #include <stdlib.h> в начале программы. Это приведет к объявлению strtol. (Кроме того, необходим #include <stdio.h> для того, чтобы объявить printf.)

  2. Добавить -Wall ваши флаги компилятора (если вы используете GCC или лязг). Это заставит компилятор сказать вам, что вам нужно объявить strtol, и это может даже предложить включить заголовок.

Что происходит в том, что вы не объявили strtol, в результате чего компилятор предполагает, что он возвращает int.

С 4294967290 является 2 -6, это 32-разрядное представление Two's-complement -6. Поскольку компилятор предполагает, что strtol возвращает int, код, который он производит, смотрит только на 32 разряда младшего разряда. Поскольку вы назначаете значение long, компилятор должен испустить код, который расширяет знак int. Другими словами, он принимает 32 разряда младшего порядка, как если бы они были целым числом со знаком (которое было бы -6), а затем расширяет этот -6 до long.

Во втором вызове printf возвращаемое значение strtol вставляется в список аргументов printf без преобразования. Вы указываете printf, что аргумент long (с использованием флага l в %ld), и, к счастью, все 64 бита находятся в списке аргументов, поэтому printf считывает их как long и печатает «правильное» значение.

Излишне говорить, что все это неопределенное поведение, и фактический результат, который вы видите, никоим образом не гарантируется; это просто так работает с вашим компилятором в вашей архитектуре. На каком-то другом компиляторе или на какой-то другой архитектуре все могло бы быть совершенно другим, включая длину бит int и long. Таким образом, приведенное выше объяснение, хотя, возможно, и интересно, не имеет практической ценности. Если бы вы просто включили правильный заголовок и, таким образом, сказали компилятору реальный тип возврата strtol, вы бы получили ожидаемый результат.

Смежные вопросы