Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Переменные, объявленные внутри блока-оператора, существуют только в пределах этого блока. Область их видимости ограничена местом их объявления.

Поиск

if (expression) {

int count = 0; // Объявление переменной в области действия // оператора if

...

}

cout << "count == " << count «'\n'; //??? ОШИБКА!!!!

При компиляции последняя строка вызовет сообщение об ошибке, поскольку переменная count объявлена вне области видимости оператора if, она не существует вне ее.

 

Бывает полезно одновременно объявлять и инициализировать переменную, управляющую циклом for.

 

типичный цикл выглядит так:

void f() {

int i;

for (i=0; i<MAX; i++)

}

В С++ можно объявить переменную для цикла непосредственно внутри него, сократив код до следующего:

Void f()

{ for (int i=0; i<MAX; i++)

...

}

Однако такое объявление действует не только в пределах видимости цикла for. Инициализация управляю­щей переменной (в данном случае i=0;) выполняется до того, как начнется цикл, таким образом, i в данном примере нопадает в область видимости f() и может использоваться любыми операторами, следующими за for.

 

Константы

 

Константы — новшество языка С++, заимствованное языком C.

Объявление переменных с ключевым словом const создает вокруг них "силовое поле", предохраняющее их от изменения во время выполнения про­граммы.

 

ПРИМЕР: Если вы объявили целую переменную count следующим образом:

const int count =1234;

Компилятор выдаст сообщение об ошибке в операторе

count++; //???

Некоторые программисты рекомендуют использовать объявления const вместо символьных констант, соз­данных с помощью #define.

Символьная константа

#define МАХ 100

определяет макрос с именем МАХ, связанный с текстом 100 (не целым значением 100).

Если МАХ использу­ется следующим образом:

for (int i=0; i<MAX; i++)

то компилятор заменит МАХ на текстовые цифры 100 и скомпилирует оператор так, как будто вы ввели эти цифры в этом месте.

Некоторые эксперты по С++ утверждают, что легко сделать ошибку при использовании символьных кон­стант, подобных МАХ. Сторонники объявления const скорее предложат вам следующее:

const int MAX = 100;

Цикл for останется таким же, а объявление МАХ истинной константой даст определенные преимущества.

• Компилятор сможет выполнить проверку типов с МАХ более строго. С++ распознает, что константа МАХ
имеет тип int, в то время как компилятор ничего не знает о типе текстового макроса МАХ.

• Turbo Debugger распознает истинную константу МАХ. Отладчикне распознает символьные константы, созданные с помощью #define.

Все это необходимо иметь в виду. К несчастью, истинная константа МАХ нуждается в постоянном месте хранения в сегменте данных программы. Многочисленные программные константы могут занимать сотни ты­сяч байтов, расходуя тем самым память. Более того, использование таких значений может потребовать отни­мающих время обращений к памяти.

Обычно символьные константы используются как эффективные коман­ды, загружающие значения прямо в регистры.

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

 

Их преимущества не настолько велики, чтобы совсем отказываться от #define.

Встраиваемые функции

Одной из печальных истин программирования на языках, подобных С и С++, является то, что на вызов функций расходуется время.

Хотя вызов функции происходит быстрее, чем вы успеете глазом моргнуть, мно­гочисленные вызовы могут ухудшить общее быстродействие программы. Полный отказ от функций — непри­емлемое решение этой проблемы! Функции делают программу модульной и более легкой для поддержки. Без функций исключительно сложно, может быть, невозможно написать даже среднюю по размерам корректно ра­ботающую программу.

С другой стороны, разворачивание циклов и устранение многочисленных вызовов функций — стиль, сбе­регающий время и улучшающий общее быстродействие программы.

Рассмотрим следующий гипотетический цикл for:

for (int i = 0; i < MAX; i++) { AnyFunction();

...

}

Если значение МАХ слишком велико, многократные вызовы AnyFunction() могут занять достаточно много драгоценного времени вдобавок к общему времени выполнения программы. Предположим, AnyFunction() на­писана следующим образом:

void AnyFunction(void)

{

cout «AnyValue «'\n';

AnyValue++;

...

}

Все это, конечно, предположительно, но один факт не вызывает сомнений: вставка тела AnyFunction() не­посредственно в цикл for ускорит выполнение программы:

for (int i = 0; i <MAX; i++)

{cout << AnyValue << '\n'; AnyValue++;

...

}

Альтернативно можно объявить функции inline (встраиваемыми), вставляя тем самым их тела в поток кода. Как это сделать, показано в листинге 1.9.

Листинг 1.9. INLINE.CPP (демонстрация встраиваемых функций)

 


1: #include < iostream.h>
2:    
3: inline int max(int a, int b)
4: {  
5: if (a >= b)
6: return a;  
7: else  
8: return b;  
9: }  
10:    
11: main()  
12: {  
13: int x, y, z;
14:    
15: cout << " X? ";
16: cin >> x;  
17: cout << " Y? ";
18: cin >> y;  
19: z = max(x , y);
20: cout << " max(a, b) == " << z << ' \n';
21: return 0;  
22: }  

Для того чтобы объявить функцию встраиваемой, напишите перед ней ключевое слово inline, как показано в строке 3. Пишется функция как обычно (строки 4-9). Ничего необычного в ее содержимом нет — все, что выполняется в любой функции, выполнится и для объявленной встраиваемой. Обычно встраиваемые функ-ции.подобные той, что определена в строках 3-9, объявляются в заголовочных файлах и включаются в каж­дый модуль, где необходимо их использование. Встраиваемую функцию необходимо полностью определить до того, как можно будет ее использовать, и включение ее текста в заголовочный файл — самый простой способ удовлетворения этого требования.

Используйте встраиваемые функции в точности так же, как вы используете обычные. Например, в строке 19 вызывается max() для определения большего из двух целых чисел с присвоением этого значения переменной z. Конечно, в скомпилированном коде Borland C++ не вызывает функцию max() в строке 19. Вместо этого компи­лятор вставляет тело функции непосредственно в программу, компилируя строку 19, как если бы она была напи­сана следующим образом:

if (x >= у)

z = x;

else z = у;

Время, сэкономленное в этом примере, минимально. Однако, если max() вызывается тысячи раз в цикле, быстродействие программы может существенно улучшится.

 

Встраиваемые функции сродни регистровым переменным. Когда вы объявляете встраиваемую функцию, вы лишь даете указание компилятору, и, если возможно, тело функции будет вставлено прямо туда, откуда эта функция вызывается. Разумеется, компилятор — не золотая рыбка, и нет гарантии, что так будет с каждой вашей командой. Если встраиваемый код, к примеру, слишком велик, то компилятор может отказаться вставить функцию в поток кода, и вместо этого сгенерирует обычный вызов. Также при компиляции программ для Turbo Debugger все встраиваемые функции будут преобразованы в обычные вызываемые функции, которые можно будет отлаживать. Хорошие программы на С++ работают корректно вне зависимости от того, как скомпилированы в них встраиваемые функции.


Управление памятью с помощью new и delete

Функ­ции malloc(), farmalloc(), farcalloc(), free(), farfree() и другие одинаково доступны для всех программ на С и С++.

Однако С++ предлагает альтернативные операторы управления памятью new и delete, которые могут делать то же самое, что и стандартные функции, и более того.

Используйте new для выделения памяти динамическим переменным. Используйте free, чтобы освободить память, выделенную new, для ее использования в последующих операторах new.

new и deleteунарные операторы, а не функции. Использование этих операторов вместо стандартных функций управления памятью дает возможность при необходимости са­мостоятельно обрабатывать ситуации управления памятью.

Чтобы выделить память для переменной, имеющей тип double, и присвоить ее адрес указателю, вы можете написать

double *dp = new double;

Вы можете часто видеть схожее объявление, делающее вызов new похожим на вызов функции:

double *dp = new(double);

Это не так, и лишние круглые скобки просто игнорируются. Используется dp так же, как и любой другой ука­затель на память, выделенную malloc() или подобной функцией.

Для присваивания значения содержимому памяти, адрес которой хранится в dp,

*dp = 3.14159;

Закончив использование динамической переменной, удалите ее следующим образом:

delete dp;

Удаление указателя означает освобождение выделенной ранее памяти, адрес которой хранится в dp, для последующего использования.

Для освобождения памяти, выделенной с помощью new, необходимо использо­вать только delete. Динамические переменные, созданныефункцией malloc(), следует уничтожать с помощью функции free() (или, возможно, farfree()). Вы можете использовать malloc() и new в одной и той же про­грамме, но вы не можете смешивать способы управления памятью С и С++.



Поделиться:


Последнее изменение этой страницы: 2016-08-01; просмотров: 166; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.118.37.85 (0.007 с.)