Подтвердить что ты не робот

Почему строка формата printf имеет как% c, так и% s?

Почему строка формата printf имеет значения %c и %s?

Я знаю, что %c представляет один символ, а %s представляет строку символов с завершающим нулем символом, но не будет ли только одно представление строки?

4b9b3361

Ответ 1

Вероятно, чтобы отличить строку с нулевым завершением и символ. Если они имели только %s, то каждый отдельный символ также должен быть нулевым.

char c = 'a';

В приведенном выше случае c должно быть завершено нулем. Это мое предположение, хотя:)

Ответ 2

%s печатает символы, пока не достигнет 0 (или '\0', то же самое).

Если у вас есть только char x;, напечатав его с printf("%s", &x); - , вам нужно будет указать адрес, так как %s ожидает, что char* - приведет к неожиданным результатам, поскольку &x + 1 может не быть 0.

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

EDIT: как указывали другие, они ожидают разные вещи в параметрах var args - один указатель, другой - один char. Но эта разница несколько ясна.

Ответ 3

Проблема, о которой говорят другие, о том, что один символ должна быть завершена нулем, не является реальной. Это можно было бы решить, предоставив точность в формате %.1s, чтобы сделать трюк.

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

Изменить: Меня действительно раздражает реакция на этот ответ, поэтому я, вероятно, удалю это, это действительно не стоит. Кажется, что люди реагируют на это, даже не прочитав вопрос или не понимая, как оценить технику вопроса.

Чтобы это было ясно: я не говорю, что вы должны предпочесть %.1s над %c. Я только говорю, что причины, по которым %c не могут быть заменены, отличаются от другого ответа, претендующего на то, чтобы рассказать. Эти другие ответы просто технически ошибочны. Устранение нулей не является проблемой при %s.

Ответ 4

Функция printf является вариационной функцией, что означает, что она имеет переменное количество аргументов. Аргументы помещаются в стек перед вызовом функции (printf). Чтобы функция printf использовала стек, ему необходимо знать информацию о том, что находится в стеке, для этой цели используется строка формата.

например.

printf( "%c", ch );    tells the function the argument 'ch' 
                       is to be interpreted as a character and sizeof(char)

тогда

printf( "%s", s );   tells the function the argument 's' is a pointer 
                     to a null terminated string sizeof(char*)

внутри функции printf невозможно определить иначе содержимое стека, например. различая "ch" и "s", потому что в C нет проверки типа во время выполнения.

Ответ 5

%s говорит, что печатает все символы, пока не найдет нуль (обработайте переменную как указатель).

%c говорит, что печатает только один символ (обрабатывает переменную как символ)

Использование %s для символа не работает, потому что символ будет обрабатываться как указатель, тогда он попытается напечатать все символы, следующие за этим местом в памяти, до тех пор, пока не найдет нуль

Похищение других ответов, чтобы объяснить это по-другому.

Если вы хотите напечатать символ с помощью %s, вы можете использовать следующее, чтобы правильно передать ему адрес char и не дать ему писать мусор на экране, пока не найдете нуль.

char c = 'c';
printf('%.1s', &c);

Ответ 6

Для %s нам нужно указать адрес строки, а не ее значение.

Для %c мы предоставляем значение символов.

Если мы использовали %s вместо %c, как бы мы предоставили '\0' после символов?

Ответ 7

Id хотел бы добавить еще одну точку зрения на этот забавный вопрос.

Действительно, это сводится к набору данных. Я видел ответы здесь о том, что вы можете указать указатель на char и предоставить

"%.1s"

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

Иногда программист может захотеть запустить серию операторов if-else или case-switch, где необходимо просто вывести символ, основанный на состоянии. Для этого жесткое кодирование символов действительно может занимать меньше места в памяти, так как одиночные символы - 8 бит по сравнению с указателем 32 или 64 бита (для 64-битных компьютеров). Указатель будет занимать больше места в памяти.

Если вы хотите уменьшить размер с помощью фактических символов или указателей на символы, тогда есть два способа думать об этом в типах printf. Один из них должен был бы отключить .1s, но как подпрограмма должна знать наверняка, что вы действительно предоставляете тип char по сравнению с указателем на char или указателем на строку (массив символов)? Вот почему они пошли с "% c", так как это другое.

Интересный вопрос: -)

Ответ 8

C имеет спецификаторы формата %c и %s, поскольку они обрабатывают разные типы.

A char и строка примерно такая же, как ночь, и 1.

Ответ 9

% c ожидает char, который является целым числом и печатает его в соответствии с правилами кодирования.

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

Итак, вы видите, что под капотом два случая, когда они выглядят одинаково, у них мало общего, так как один работает со значениями, а другой с указателями. Один из них - это инструкции для интерпретации определенного целочисленного значения как ascii char, а другой - итерации содержимого ячейки памяти char на char и интерпретации их до тех пор, пока не встретится нулевое значение.

Ответ 10

Поскольку никто не предоставил ответа с ЛЮБОЙ ссылкой вообще, вот спецификация printf из pubs.opengroup.com, которая похожа на формат IBM

% с

Аргумент int должен быть преобразован в unsigned char, и полученный байт должен быть записан.

% s

Аргумент должен быть указателем на массив из char. Байты из массива записываются в (но не включая) любой завершающий нулевой байт. Если задана точность, должно быть записано не более того, что должно быть записано много байтов. Если точность не указана или больше размера массива, приложение должно гарантировать, что массив содержит нулевой байт.

Ответ 11

Я провел эксперимент с printf("%.1s", &c) и printf("%c", c). Я использовал следующий код для тестирования, а утилиту bash time - время выполнения.

    #include<stdio.h>
    int main(){
        char c = 'a';
        int i;
        for(i = 0; i < 40000000; i++){
            //printf("%.1s", &c); get a result of 4.3s
            //printf("%c", c); get a result of 0.67s
        }
        return 0;
    }

В результате говорится, что использование %c в 10 раз быстрее, чем %.1s. Таким образом, хотя% s может выполнять задание% c,% c по-прежнему необходимо для производительности.