
Тельнов / ООП Лекция 6 Дополнительные возможности Си
.ppt
Введение в С++
Дополнительные возможности

Дополнительные возможности Си
Защита указателей и объектов
Ключевое слово const при описании объекта указывает на то, что значение данного объекта не может изменяться.
Примеры:
const pi = 3.14; |
// это константа (используется вместо директивы #define ) |
|
const char *ps; |
// указатель на постоянный объект |
|
const char s[5] = “abcd”; |
// постоянный массив символов |
|
ps = s; |
// так можно |
|
*(ps + 1) = “x”; |
// так нельзя, объект защищен от изменения |
|
сhar* const ps = s; |
// постоянный указатель на объект |
|
ps = “dcba”; |
// так нельзя, указатель защищен от изменения |
|
*(ps + 2) = “z”; |
// так можно, защищен указатель на объект, а не сам объект |
|
const char* const ps = s; |
// постоянный указатель на постоянный объект |
// защита аргументов функций от изменения: сhar* strcpy ( char* to, const char* from );

Дополнительные возможности Си
Перегруженные функции
Можно иметь несколько вариантов одной и той же функции (перегрузка функции).
Сигнатура вариантов функции должна отличаться, лишь имя функции
остается неизменным. |
|
Примеры: |
// функция с именем length будет перегружена |
overload length; |
//функция length вычисляет длину вектора на плоскости, длину
//вектора в трехмерном пространстве и длину строки в байтах
float length (int x, int y) { return sqrt ( x*x + y*y ); } |
// на плоскости |
|
float length (int x, int y, int z) { return sqrt ( x*x + y*y + z*z ); } // в пространстве |
||
int length ( char *s ) { return charWidth * strlen( s ); } |
// длина строки в байтах |
|
// вызовы функции |
|
|
length ( 1, 5 ); |
// на плоскости |
|
length ( 1, 0, 3 ); |
// в пространстве |
|
length ( name ); |
// длина строки в байтах |
|

Дополнительные возможности Си
Inline-функции
Inline-функции используются как альтернатива макросам.
Они лишены главного недостатка макросов – побочных эффектов.
От обычных функций отличаются тем, что тело функции встраивается непосредственно в код в том месте, где происходит вызов inline-функции. Программный стек не используется, тем самым достигается максимальная скорость вызова функции.
Пример:
#define ABS ( a ) ( (a ) > 0 ? ( a ) : - ( a ) ); |
// пусть есть такой макрос |
// тогда выражение |
|
b = ABS ( ++s ); |
|
// расширится в следующее: |
|
b = ( ( ++s ) > 0 ? ( ++s ) : - ( ++s ) ); |
// неустранимый побочный эффект |
// следующая inline-функция |
|
inline int abs ( int a ) { return a > 0 ? a : -a ; |
} |
b = abs ( ++s ); |
// расширится верно |
|
|

Дополнительные возможности Си
Ссылочные типы
Можно одному и тому же объекту давать несколько имен.
Наиболее часто ссылочные типы используются для передачи аргументов «по ссылке», при этом указатели явным образом не применяются. Примеры:
int a = 1; |
// если b = 3, то значение a также станет равным 3 |
||
int &b = a; |
// b есть синоним (второе имя) переменной a |
||
struct point { float x, y; }; |
// декартовы координаты точки на плоскости |
||
void polar1 ( struct point *p, float r, float f ) |
// из полярных координат в декартовы |
||
{ p->x = r * cos ( f ); |
p->y = r * sin ( f ); } |
|
|
// или можно так: |
|
|
|
{ ( *p ).x = r * cos ( f ); ( *p ).y = r * sin ( f ); |
} |
||
// второй вариант – используем ссылочный тип и значения по умолчанию |
|||
void polar2 ( point &d, float r = 1., float f = 0. ) |
|||
{ d.x = r * cos ( f ); |
d.y = r * sin ( f ); } |
|
|
// обращение к функциям: |
|
|
|
point z; |
// описана структурная переменная |
||
polar1 ( &z, 1., 0. ); |
// без ссылочных типов, используем указатель |
||
polar2 ( z ); |
// используем ссылочный тип, работаем с оригиналом аргумента |
||
|
|
|
|