Литмир - Электронная Библиотека
A
A

struct pair { int x,y; };

pair p1;        /* ошибка: идентификатора pair не в области

                /* видимости */

struct pair p2; /* OK */

int pair = 7;   /* OK: дескриптора структуры pair нет в области

                /* видимости */

struct pair p3; /* OK: дескриптор структуры pair не маскируется

                /* типом int*/

pair = 8;       /* OK: идентификатор pair ссылается на число типа

                /* int */

Довольно интересно, что, применив обходной маневр, этот прием можно заставить работать и в языке С++. Присваивание переменным (и функциям) тех же имен, что и структурам, — весьма распространенный трюк, используемый в программах на языке С, хотя мы его не рекомендуем.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Если вы не хотите писать ключевое слово
struct
перед именем каждой структуры, используйте оператор
typedef
(см. раздел 20.5). Широко распространена следующая идиома:

typedef struct { int x,y; } pair;

pair p1 = { 1, 2 };

В общем, оператор

typedef
используется чаще и является более полезным в программах на языке С, в которых у программиста нет возможности определять новые типы и связанные с ними операции.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _003.png
 В языке C имена вложенных структур находятся в том же самом пространстве имен, что и имя структуры, в которую они вложены. Рассмотрим пример.

struct S {

  struct T { /* ... */ };

  / * ... */

};

struct T x; /* OK в языке C (но не в C++) */

В программе на языке C++ этот фрагмент следовало бы написать так:

S::T x; // OK в языке C++ (но не в C)

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

27.3.2. Ключевые слова

Многие ключевые слова в языке C++ не являются ключевыми словами в языке С (поскольку язык С не обеспечивает соответствующие функциональные возможности) и поэтому могут использоваться как идентификаторы в программах на языке C.

Программирование. Принципы и практика использования C++ Исправленное издание - _339.png

 

Программирование. Принципы и практика использования C++ Исправленное издание - _003.png
 Не используйте эти имена как идентификаторы в программах на языке C, иначе ваш код станет несовместимым с языком C++. Если вы используете одно из этих имен в заголовочном файле, то не сможете использовать его в программе на языке C++.

Некоторые ключевые слова в языке C++ являются макросами в языке C.

Программирование. Принципы и практика использования C++ Исправленное издание - _340.png

В языке C они определены в заголовочных файлах

<iso646.h>
и
<stdbool.h>
(
bool
,
true
,
false
). Не пользуйтесь тем, что они являются макросами в языке C.

27.3.3. Определения

Язык C++ допускает определения в большем количестве мест программы по сравнению с языком C. Рассмотрим пример.

for (int i = 0; i<max; ++i) x[i] = y[i]; // определение переменной i,

                                         // недопустимое в языке C

while (struct S* p = next(q)) { // определение указателя p,

                                // недопустимое в языке C

  /* ... */

}

void f(int i)

{

  if (i< 0 || max<=i) error("Ошибка диапазона");

  int a[max]; // ошибка: объявление после инструкции

              // в языке С не разрешено

  /* ... */

}

Язык C (C89) не допускает объявлений в разделе инициализации счетчика цикла

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

int i;

for (i = 0; i<max; ++i) x[i] = y[i];

struct S* p;

while (p = next(q)) {

  /* ... */

}

void f(int i)

{

  if (i< 0 || max<=i) error("Ошибка диапазона");

  {

    int a[max];

    /* ... */

  }

}

В языке С++ неинициализированное объявление считается определением; в языке С оно считается простым объявлением, поэтому его можно дублировать.

int x;

int x; /* определяет или объявляет одну целочисленную переменную

          с именем x в программе на языке C; ошибка в языке C++ */

 

Программирование. Принципы и практика использования C++ Исправленное издание - _003.png
 В языке С++ сущность должна быть определена только один раз. Ситуация становится интереснее, если эти две переменные типа
int
с одинаковыми именами находятся в разных модулях компиляции.

/* в файле x.c: */

389
{"b":"847443","o":1}