В C, что означает «аргумент формата может быть выражением тоже»? - PullRequest
2 голосов
/ 07 марта 2012

В книге K & R она показывает следующую инструкцию printf в главе указателей:

printf((argc > 1) ? "%s " : "%s", *++argv);

Я не понимаю эту строку - почему здесь два% s?

Спасибо!

Ответы [ 7 ]

7 голосов
/ 07 марта 2012

Это эквивалентно:

if ( argc > 1 )
    printf("%s ", *++argv);
else
    printf("%s", *++argv);

Это троичный условный оператор:

(condition) ? (subexpression1) : (subexpression2)

Выражение оценивается как subexpression1, если condition равно true и subexpression2в противном случае.

2 голосов
/ 07 марта 2012

Первый аргумент для этого printf это (argc > 1) ? "%s " : "%s", который является троичным условным выражением (см. Страницу википедии на ?: ) Условие здесь (argc > 1) затем подвыражение - "%s " (буквенная константная строка), под-выражение else - "%s".

Гораздо более распространенное использованиеФормат выражения к printf должен вызывать некоторую функцию интернационализации или локализации, такую ​​как gettext (на самом деле, многие программы даже определяют макрос, названный одним символом, часто _, для него).

1 голос
/ 07 марта 2012

Поскольку это выражение (condition) ? (if true) : (if false) является Тернарный оператор . И "%s " будет выполняться, если условие будет true, и "%s", если false.

1 голос
/ 07 марта 2012

Чтобы после имени был пробел, если есть хотя бы один аргумент.

И в основном, чтобы продемонстрировать, что вы также можете сделать:

const char *format = "%s";
if (argc > 1)
    format = "%s ";
printf(format, *++argv);

Что делает более понятным, что строка формата может быть переменной. Тем не менее, вы должны быть осторожны с уязвимостями «внедрения формата». Если пользователь может контролировать содержимое строки формата, ваша программа уязвима для атаки.

1 голос
/ 07 марта 2012

В С? обозначает условный оператор.

Выражение:

A ? B : C

оценивается как B, если A не равен нулю, и оценивается как C, если A оценивается как 0.

Так что в вашем случае, если argc> 1, он выведет текущие параметры с пробелом после него. В противном случае он выведет текущий параметр без пробела

1 голос
/ 07 марта 2012

Это сокращение для оператора if, называемое «тернарный оператор».

(argc > 1) ? "%s " : "%s" 

означает

if (argc > 1) 
  "%s "
else
  "%s"

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

1 голос
/ 07 марта 2012

Вы используете троичный оператор .Это заставляет printf использовать "%s" в качестве строки формата, если argc меньше или равно 1 и "%s ", если argc больше 1

...