#c #printf #character #c-strings #conversion-specifier
Вопрос:
#include <stdio.h>
int main(void)
{
char var = 'z';
printf("[buf]: %s n", amp;var); // the output is z~~~~~, but the first char of output is only z. why??
}
Комментарии:
1.
%s
это для строк, так как же это все равно напечатает адрес? Кроме того, это неопределенное поведение. После этого не будет НУЛЕВОГО терминатораz
.
Ответ №1:
Спецификатор преобразования s
предназначен для вывода строк (или их частей): последовательностей символов, заканчивающихся нулевым символом ''
.
Для вывода адреса объекта существует спецификатор преобразования p
.
Вот демонстрационная программа.
#include <stdio.h>
int main(void)
{
char s[] = "Hello";
printf( "%sn", s );
printf( "%pn", ( void * )s );
return 0;
}
Вывод программы может выглядеть следующим образом
Hello
0x7ffc86fe4372
Что касается кода в вашем вопросе, то он имеет неопределенное поведение, потому что выражение amp;var
не указывает на строку, потому что переменная var
определена следующим образом
char var = 'z';
Если вы хотите вывести его адрес, то вы можете сделать это следующим образом
printf("[buf]: %p n", ( void * )amp;var);
Ответ №2:
%s
указывает printf
принять указатель на первый символ строки и распечатать эту строку, вплоть до нулевого символа, указывающего на ее конец. Поскольку вы передаете адрес одного символа, printf
печатает его и продолжает искать в памяти дополнительные символы для печати, пока не найдет байт, содержащий ноль. Поскольку %s
, когда вы передаете указатель на один символ, а не на массив символов, заканчивающийся нулевым символом, поведение не определяется стандартом C.
Чтобы напечатать адрес, используйте %p
и преобразуйте указатель в void *
:
printf("%pn", (void *) amp;var);