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

на главную - закладки

Жанры

Программирование. Принципы и практика использования 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
, используя минимальные обозначения.

(T)v

Это так называемое “приведение в стиле языка С”, или “приведение в старом стиле”. Его любят люди, не умеющие набирать тексты (за лаконичность) и ленивые (потому что они не обязаны знать, что нужно для того, чтобы из переменной
v
получилась переменная типа
T
). С другой стороны, этот стиль яростно отвергают программисты, занимающиеся сопровождением программ, поскольку такие преобразования остаются практически незаметными и никак не привлекают к себе внимания. Приведения в языке С++ (приведения в новом стиле (new-style casts), или приведения в шаблонном стиле (template-style casts); см. раздел А.5.7) осуществляют явное преобразование типов, которое легко заметить. В языке С у вас нет выбора.

int* p = (int*)7; /* интерпретирует битовую комбинацию:

reinterpret_cast<int*>(7) */

int x = (int)7.5; /* усекает переменную типа: static_cast<int>(7.5) */

typedef struct S1 { /* ... */ } S1;

typedef struct S2 { /* ... */ } S2;

S1 a;

const S2 b; /* в языке С допускаются неинициализированные

/* константы */

Поделиться:
Популярные книги

Неудержимый. Книга XVII

Боярский Андрей
17. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVII

Энфис 3

Кронос Александр
3. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 3

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Генерал Империи

Ланцов Михаил Алексеевич
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Генерал Империи

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке

Брак по-драконьи

Ардова Алиса
Фантастика:
фэнтези
8.60
рейтинг книги
Брак по-драконьи

Авиатор: назад в СССР

Дорин Михаил
1. Авиатор
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Авиатор: назад в СССР

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Камень. Книга шестая

Минин Станислав
6. Камень
Фантастика:
боевая фантастика
7.64
рейтинг книги
Камень. Книга шестая

Неудержимый. Книга X

Боярский Андрей
10. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга X

Воин

Бубела Олег Николаевич
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Воин

Менталист. Эмансипация

Еслер Андрей
1. Выиграть у времени
Фантастика:
альтернативная история
7.52
рейтинг книги
Менталист. Эмансипация

Делегат

Астахов Евгений Евгеньевич
6. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Делегат

Кодекс Охотника. Книга XXVI

Винокуров Юрий
26. Кодекс Охотника
Фантастика:
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXVI