В языке C++, но не в С, значения const можно использовать для инициализации других значений const:
const double RATE = 0.06; // допустимо в C++, С
const double STEP =24.5; // допустимо в C++, С
const double LEVEL = RATE * STEP; // допустимо в C++, недопустимо в С
914 Приложение Б
Структуры и объединения
После объявления структуры или объединения с дескриптором в C++ этот дескриптор можно применять в качестве имени типа:
struct duo
{
int а; int b;
};
struct duo m; /* допустимо в С, C++ */
duo n; /* недопустимо в С, допустимо в C++ */
В результате имя структуры может конфликтовать с именем переменной. Например, следующая программа компилируется как программа на С, но не может быть успешно скомпилирована как программа на C++, поскольку C++ интерпретирует duo в операторе printf() как тип структуры, а не как внешнюю переменную:
#include float duo = 100.3; int main(void)
{
struct duo { int a; int b,(); struct duo у = { 2, 4};
printf ("%f\n", duo); /* допустимо в С, но не в C++ */ return 0;
}
В С и C++ можно объявлять одну структуру внутри другой:
struct box
{
struct point {int x; int y; } upperleft; struct point lowerright;
};
В языке С любую из структур можно использовать позже, но C++ требует специальной формы записи для вложенной структуры:
struct box ad; /* допустимо в С, C++ */
struct point dot; /* допустимо в С, недопустимо в C++ */
box::point dot; /* недопустимо в С, допустимо в C++*/
Перечисления
Язык C++ строже С в отношении применения перечислений. В частности, практически единственное, что можно делать с переменной enum — это присваивать ей константу enum и сравнивать ее с другими значениями. Нельзя присваивать значения int nеременной enum без явного приведения типа, равно как не допускается инкрементировать переменную enum. Следующий код иллюстрирует эти утверждения:
enum sample {sage, thyme, salt, pepper}; enum sample season;
season = sage; /* допустимо в С, C++ */
season = 2; /* предупреждение в С, ошибка в C++ */
season = (enum sample) 3; /* допустимо в С, C++ */
season++; /* допустимо в С, ошибка в C++ */
Справочные материалы 915
Кроме того, C++ позволяет не указывать ключевое слово enum при объявлении переменной:
enum sample {sage, thyme, salt, pepper};
sample season; /* недопустимо в С, допустимо в C++ */
Как в случае со структурами и объединениями, это может привести к конфликтам, если имена переменной и типа enum совпадают.
Указатель на void
В языке C++, как и в С, указателю на void можно присвоить указатель любого типа, но в отличие от С, указатель на void нельзя присваивать указателю другого типа без явного приведения. Сказанное демонстрируется в следующем коде:
int ar[5] = {4, 5, 6,7, 8}; int * pi; void * pv;
pv = ar; /* допустимо в С, C++ */
pi = pv; /* допустимо в С, недопустимо в C++ */
pi = (int * ) pv; /* допустимо в С, C++ */
Еще одно отличие C++ заключается в том, что вы можете присваивать адрес объ
екта производного класса указателю на базовый класс, но это относится к возможностям, которые в С отсутствуют.
Булевские типы
В языке C++ булевский тип называется bool, a true и false являются ключевыми словами. В языке С булевский тип имеет название Bool, но включение заголовочного файла stdbool.h делает доступными bool, true и false.
Альтернативное написание
В C++ альтернативное написание or для || и прочих операций обеспечивается ключевыми словами. В С99 и С11 альтернативные написания определены в виде макросов, и для того, чтобы сделать их доступными, необходимо включить заголовочный файл iso64 6.li.
Поддержка широких символов
В C++ тип wchar t является встроенным, a wchar t — ключевым словом. В С99 и C11 тип wchar t определен в нескольких заголовочных файлах (stddef.h, stdlib.h, wchar.h, wctype.h). Подобным же образом, charl6_t и char32_t — это ключевые слова в С++11, но макросы, определенные в uchar.li, в СИ.
Язык C++ предоставляет поддержку ввода-вывода широких символов (wchar t, charl6_t и char32_t) через заголовочный файл iostream, тогда как С99 предлагает совершенно другой пакет поддержки ввода-вывода, доступный через заголовочный файл wchar.h.
Комплексные типы
Язык C++ поддерживает комплексные типы посредством класса complex, предоставляемого с помощью заголовочного файла complex. Язык С имеет встроенные комплексные типы и поддерживает их через заголовочный файл complex.h. Эти два подхода существенно отличаются и несовместимы друг с другом. Версия С в большей степени отражает практические потребности вычислительного сообщества.
916 Приложение Б
Встраиваемые функции
В стандарте С99 была добавлена поддержка встраиваемых функций — средства, которое давно существовало в языке C++. Однако их реализация в С99 является более гибкой. В C++ встраиваемая функция по умолчанию имеет внутреннее связывание. Если встраиваемая функция C++ появляется в более чем одном файле, то она должна иметь одно и то же определение, используя те же самые лексемы. Например, один файл не может иметь определение с параметром типа int, а другой — определение с параметром типа int32_t, несмотря на то, что int32_t — это typedef для int. Гем не менее, в С такая организация разрешена. Кроме того, как было описано в главе 15, язык С позволяет смешивать встраиваемые и внешние определения, что в C++ не допускается.
Читать дальше