Чтение онлайн

ЖАНРЫ

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

typedef struct { int x,y; } pair;

pair p1 = { 1, 2 };

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

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

В языке 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, иначе ваш код станет несовместимым с языком C++. Если вы используете одно из этих имен в заголовочном файле, то не сможете использовать его в программе на языке C++.

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

В языке 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++ */

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

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

int x;

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

int x;

Ни компилятор языка С, ни компилятор языка С++ не найдет никаких ошибок в файлах

x.c
или
y.c
. Но если файлы
x.c
и
y.c
скомпилировать как файлы на языке С++, то редактор связей выдаст сообщение об ошибке, связанной с двойным определением. Если же файлы
x.c
и
y.c
скомпилировать на языке C, то редактор связей не выдаст сообщений об ошибке и (в полном соответствии с правилами языка C) будет считать, что речь идет об одной и той же переменной
x
, совместно используемой в файлах
x.c
и
y.c
. Если хотите, чтобы в программе всеми модулями совместно использовалась одна глобальная переменная
x
, то сделайте это явно, как показано ниже.

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

int x = 0; /* определение */

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

extern int x; /* объявление, но не определение */

Впрочем, лучше используйте заголовочный файл.

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

extern int x; /* объявление, но не определение */

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

#include "x.h"

int x = 0; /* определение */

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

#include "x.h"

/* объявление переменной x находится в заголовочном файле */

А еще лучше: избегайте глобальных переменных.

27.3.4. Приведение типов в стиле языка С

В языке C (и в языке C++) можете явно привести переменную

v
к типу
T
, используя минимальные обозначения.

Поделиться с друзьями: