Рубрики

Тернарный оператор C / C ++ — некоторые интересные наблюдения

Предсказать вывод следующей программы на C ++.

#include <iostream>

using namespace std;

  

int main()

{

   int test = 0;

   cout << "First  character " << '1' << endl;

   cout << "Second character " << (test ? 3 : '1') << endl;

  

   return 0;

}

Можно ожидать, что результат будет одинаковым в обоих операторах печати. Тем не менее, выход будет,

First  character 1
Second character 49

Почему второе утверждение печатается 49? Читайте на троичном выражении.

Тернарный оператор (C / C ++):

Тернарный оператор имеет следующую форму:

опыт 1 ? опыт 2 : опыт 3

Выражение exp 1 будет оцениваться всегда. Выполнение опыта 2 и опыта 3 зависит от результата опыта 1 . Если результат exp 1 отличен от нуля, exp 2 будет оцениваться, иначе exp 3 будет оцениваться.

Побочные эффекты:

Любые побочные эффекты опыта 1 будут оцениваться и обновляться непосредственно перед выполнением опыта 2 или опыта 3 . Другими словами, есть точка последовательности после оценки состояния в троичном выражении. Если у exp 2 или exp 3 есть побочные эффекты, будет оцениваться только один из них.

Тип возврата:

Это еще один интересный факт. Тернарный оператор имеет тип возврата. Тип возврата зависит от exp 2 и конвертируемости exp 3 в exp 2 согласно обычным / перегруженным правилам конвертации. Если они не конвертируемы, компилятор выдает ошибку. Смотрите примеры ниже,

Следующая программа компилируется без ошибок. Ожидается, что возвращаемым типом троичного выражения будет float (как в exp 2 ), а exp 3 (т. Е. Буквальный ноль — тип int ) неявно преобразуется в float.

#include <iostream>

using namespace std;

  

int main()

{

   int test = 0;

   float fvalue = 3.111f;

   cout << (test ? fvalue : 0) << endl;

  

   return 0;

}

Следующая программа не будет компилироваться, потому что компилятор не может найти возвращаемый тип троичного выражения, или неявное преобразование недоступно между exp 2 ( массив символов ) и exp 3 ( int ).

#include <iostream>

using namespace std;

  

int main()

{

   int test = 0;

   cout << test ? "A String" : 0 << endl;

  

   return 0;

}

Следующая программа * может * скомпилироваться или потерпит неудачу во время выполнения. Возвращаемый тип троичного выражения ограничен типом ( char * ), но выражение возвращает int , поэтому программа завершается с ошибкой. Буквально программа пытается напечатать строку по 0-му адресу во время выполнения.

#include <iostream>

using namespace std;

  

int main()

{

   int test = 0;

   cout << (test ? "A String" : 0) << endl;

  

   return 0;

}

Мы можем заметить, что exp 2 считается типом вывода, а exp 3 будет преобразован в exp 2 во время выполнения. Если преобразование неявное, компилятор вставляет заглушки для преобразования. Если преобразование явное, компилятор выдает ошибку. Если какой-либо компилятор пропустит такую ошибку, программа может завершиться с ошибкой во время выполнения.

Лучшая практика:

Это сила системы типов C ++, которая позволяет избежать таких ошибок. Убедитесь, что оба выражения exp 2 и exp 3 возвращают один и тот же тип или по крайней мере безопасно конвертируемые типы. Мы можем видеть другие идиомы, такие как C ++ convert union для безопасного преобразования.

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

Рекомендуемые посты:

Тернарный оператор C / C ++ — некоторые интересные наблюдения

0.00 (0%) 0 votes