Что если я попытаюсь напечатать большие целые, используя% c и% s? - PullRequest
0 голосов
/ 26 сентября 2019

Если я попытаюсь напечатать 1000, как указано в C:

printf("%c\n",1000);
printf("%s\n",1000);

Какой будет вывод? Или я получу ошибку для обеих строк?

Ответы [ 3 ]

4 голосов
/ 26 сентября 2019
printf("%c\n",1000);

%c требует аргумент типа int (пока все хорошо) и печатает его как символ.1000 (почти наверняка) выходит за пределы диапазона char или unsigned char, но

Если модификатор длины l отсутствует, аргумент int преобразуется в unsigned charи результирующий символ записывается.

Преобразование в целочисленный тип без знака хорошо определено;уменьшено по модулю UCHAR_MAX+1.Предполагая UCHAR_MAX==255 (что почти наверняка), результатом преобразования будет (unsigned char)232, поэтому он будет (пытаться) напечатать символ 232. Результат, вероятно, будет зависеть от локали.Вероятно, вы столкнетесь с проблемами, поскольку 232 (0xe8) является недопустимой кодировкой UTF-8.

printf("%s\n",1000);

%s требует аргумент типа char*.поэтому поведение не определено.(На практике может случиться так, что значение 1000 обрабатывается так, как если бы оно было указателем. Маловероятно, что это действительный адрес или допустимая строка, начинающаяся с этого адреса.)

2 голосов
/ 26 сентября 2019

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

В случае printf("%s\n",1000); вы просто лжете компилятору и говорите емучто 1000 является указателем на выделенную строку символов.Трудно точно сказать, что произойдет - возможно, компилятор убежит по адресу 1000 и попытается получить к нему доступ, что может привести к сбою.

В случае printf("%c\n",1000); это на самом деле несколько детерминированное поведение,случайно.Все аргументы переменных функций, таких как printf, неявно продвигаются.Если бы вы передали char, он был бы повышен до int, а затем преобразован обратно в char.

Но вы передали целочисленную константу 1000, которая имеет тип int.Как это происходит, printf ожидает int после неявного повышения и попытается преобразовать 1000 «назад» в char.Это означает, что компилятор захватит младший значащий байт int и обработает его как char (или быть разборчивым, как unsigned char).

1000 == 0x000003E8.Преобразование char захватит младший значащий байт E8.А затем выведите то, что этот символ представляет в таблице символов, если что-нибудь.

0 голосов
/ 26 сентября 2019

Пожалуйста, обратитесь к спецификаторам формата printf: http://www.cplusplus.com/reference/cstdio/printf/

%c - используется для печати символа (char), который обычно имеет значение от -128 до 127 (это также может бытьОт 0 до 255)

%s - используется для печати массива char s с последним символом как NULL (\0)

Так что printf("%c\n",1000); демонстрирует реализацию, определеннуюповедение 1000 больше 128 (или 255).

и printf("%s\n",1000); пытается распечатать массив символов, расположенных по адресу 1000 (что, скорее всего, неверно).Это также неопределенное поведение, поэтому может произойти все, что угодно.

Если вы пытаетесь вывести целое число, вы должны использовать %d, например:

printf("%d\n",1000);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...