#c #syntax #printf #conditional-operator
#c #синтаксис #printf #условный оператор
Вопрос:
После прочтения этого я начал думать, что узнал много интересного printf()
. Внезапно я обнаружил следующий фрагмент кода из этой книги:
int main()
{
char str[]="Hello";
int i=5,j=10;
printf(i>j?"Ps":"%s",str); //unable to understand this
return 0;
}
Удивительно, что приведенный выше код выполняется без ошибок и выводит привет.
Насколько мне известно, ниже приведен синтаксис printf()
:
int printf(const char *format,argument_list);
Итак, согласно этому синтаксису, printf()
должен начинаться со строки формата. Но, как вы можете видеть в приведенном выше коде, printf()
начинается с i>j
.
Означает ли это, что я ошибаюсь в интерпретации синтаксиса printf()? Является ли размещение троичного оператора внутри printf() особым случаем?
Редактировать
Я знаю о троичном операторе, я спрашиваю о первом аргументе printf()
, который должен быть const char *, которого, как мне кажется, нет в моем примере.
Комментарии:
1. Результатом выражения внутри 1-го параметра должен быть указатель на постоянный массив символов, так что ничего удивительного.
2. вы имеете в виду, что все, что даже без двойных кавычек, является указателем на постоянную строку
3. может быть, все станет понятнее, если вы напишете это таким образом:
printf((i>j?"Ps":"%s"), str)
4. @A.s.Bhullar оба
"Ps"
и"%s"
на самом деле являются указателями на постоянные массивы символов.i>j?"Ps":"%s"
является выражением. Результатом этого выражения должен быть указатель на постоянный массив символов. Я думаю, вы путаетеconst char *
с постоянным выражением, что не одно и то же
Ответ №1:
Условный оператор:
i>j?"Ps":"%s"
является выражением, и оно должно быть вычислено до того, как может быть вычислен сам вызов функции. Мы можем убедиться в этом, перейдя к проекту стандартного раздела C99 « 6.5.2.2
Вызовы функций«, в котором говорится:
Аргументом может быть выражение любого типа объекта. При подготовке к вызову функции вычисляются аргументы, и каждому параметру присваивается значение соответствующего аргумента.81)
Итак, каков результат вычисления условного оператора? Если мы перейдем к разделу 6.5.15
Условный оператор, он говорит (курсив мой):
Вычисляется первый операнд; после его вычисления есть точка последовательности. Второй операнд вычисляется, только если первое сравнение не равно 0; третий операнд вычисляется, только если первое сравнение равно 0; результатом является значение второго или третьего операнда (в зависимости от того, что вычисляется), преобразованное в тип, описанный ниже.95
таким образом, в любом случае результатом является строковый литерал, который будет распадаться на указатель на char, который удовлетворяет требованию для первого аргумента printf
.
Комментарии:
1. Хорошее объяснение!! Но я все еще сомневаюсь в выражении i> j?»Ps»:»%s» то есть я не думаю, что это const char * , я думаю, что это должно быть заключено в двойные кавычки. Разве это не так?
2. Хорошо, теперь я понимаю, что после вычисления выражения в качестве аргумента printf() передается только «%s»
Ответ №2:
Этот код является обычным и не является каким-либо особым случаем. Требование для printf
заключается в том, что первый аргумент должен иметь тип const char*
, но это не обязательно означает, что он должен быть строковым литералом типа "%s"
. Все это означает, что вам нужно передать в качестве первого аргумента выражение типа const char*
. И i>j?"Ps":"%s"
выполняет это требование.
Комментарии:
1. Можете ли вы, пожалуйста, привести какой-либо пример const char *, который не полностью заключен в двойные кавычки?
2.
i>j?"Ps":"%s"
имеет типconst char *
(технически это такconst char []
, но здесь это не имеет значения), поэтому я думаю, что это ваш пример. Другим примером может бытьfunc()
, гдеfunc
— возвращаемая функцияconst char*
.
Ответ №3:
Я думаю, вы хорошо поняли printf
синтаксис, но я думаю, что вам чего-то не хватает в синтаксисе C.
Существует форма инструкции «compact IF like», отформатированная следующим образом: ( условие? истина : ложь )
Например, вы можете сделать :
int a=5;
int b=(a==5 ? 128 : 256);
int c=(a!=5 ? 8 : 9);
В этом случае b=128 и c=9.
Другой пример :
int flag=1;
printf("The value is: %s", (flag!=0 ? "true" : "false) );
В этом случае вы можете видеть: значение равно true
На вашем примере :
printf(i>j?"Ps":"%s",str);
если значение i выше, чем j, вы используете формат «Ps», а если значение i ниже, вы используете формат «%s»
Это может быть вид, подобный :
if (i>j)
printf("Ps",str);
else
printf("%s",str);
Вы можете видеть преимущество компактного теста.
Ответ №4:
Это троичный оператор, и в этом случае условие i> j равно false, поэтому %s будет передан в качестве параметра в printf, который выведет значение массива символов, которое является hello.
Ответ №5:
Означает ли это, что я ошибаюсь в интерпретации синтаксиса printf()?
Нет, вы не интерпретируете это неправильно.
Является ли размещение троичного оператора внутри printf() особым случаем?
В C вы можете сказать, что это выражение, а не оператор
Ваш код эквивалентен:
if (i > j)
printf("Ps", str);
else
printf("%s", str);
Ответ №6:
Троичный оператор — это просто встроенный, if
который используется как выражение (в то время как обычный if
используется для создания блока). Ваша строка равна этому:
if (i > j)
printf("Ps", str);
else
printf("%s", str);
Ответ №7:
if(i>j)
printf("Ps",str);
else
printf("%s",str);
Следовательно, Hello
печатается в обеих ситуациях
Ответ №8:
В: Означает ли это, что я ошибаюсь в интерпретации синтаксиса printf()?
A: Нет, просто нужно расширить то, что допустимо.
Вопрос: Является ли размещение троичного оператора внутри printf() особым случаем?
A: Нет ?:
не является чем-то особенным, но на первый взгляд иногда сбивает с толку.
Формат, предоставляемый printf()
, не обязательно должен быть литералом. Это может быть любая строковая переменная.
int main() {
char str[]="Hello";
char *format;
int i,j;
i = 5; j = 10;
format = i > j ? "Ps" : "%s";
printf(format, str);
i = 10; j = 5;
format = i > j ? "Ps" : "%s";
printf(format, str);
return 0;
}
Ответ №9:
Существует оператор вида: условие?следствие:альтернатива.
Условие проверяется, и если оно верно, вы получите результат. в противном случае вы получите альтернативу.
Например:
5>3 ? 10 : 5
значение 5> 3 равно true, поэтому вы получите 10.