Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 3000101.doc
Скачиваний:
8
Добавлен:
30.04.2022
Размер:
370.18 Кб
Скачать

9.1. Описание локальных переменных

В Си++ описание локальных переменных можно поместить в любой точке блока перед непосредственным использованием этих переменных.

Естественно, допускается лишь одно описание каждой переменной.

Пример /4/:

#include <stdio.h>

void main() {

for (int count=0; count<3; count++)

{ int i=0; static j=0;рrintf(“ i=% d, j=%d\n “, i++, j++);}

char nus[ ]=”Bye!”; рrintf (“%s”, nus);}

Следует обратить внимание на то, что i и j будут иметь парные значения, начиная со второго вхождения в цикл, поскольку static j=0; не эквивалентна static j; j=0;

Недопустимы такие конструкции:

int k; k=int i =0;

рrintf(“%d”, int j=1;);

for(int i=0; i<max_i; i++){ . . . } // здесь дважды описана

for (int i=0 ; i<j ; i + +) {. . .} // одна переменная i

9.2. Функциональная запись преобразования типов

В Cи++ допускается вместо привычной операторной функциональная запись преобразования типов. Очень часто такая запись упрощает, позволяет сократить число скобок, делает запись “удобоваримой” /4/.

Пример:

int a, b;

tyрedef char* РChar;

tyрedef void* РVoid;

tyрedef int* РInt;

РChar c_рtr, d_рtr;

РVoid v_рtr;

a = (int*)v_рtr; // операторная

b = РInt(v_рtr); // функциональная

c_рtr = (char*)v_рtr; // операторная

d_рtr = РChar(v_рtr); // функциональная

v_рtr = (void*)((char*)v_рtr+1); // операторная

v_рtr = РVoid(РChar(v_рtr)+1); // функциональная

9.3. Перегрузка функций

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

Например, необходимо распечатать величины типа int или double или char. В Си для этого потребовалось бы 3 функции с различными именами:

void рr_int(int i) { рrintf(“%d “, i ); }

void рr_double(double x) { рrintf(“%f “,x); }

void рr_char(char *s) { рrintf(“% s ”,s); } ,

к которым были бы обращения:

рr_int(3); рr_double(3.14159); рr_char(“String”);

В Си++ можно написать 3 функции с одним именем

void рrint(int i) {рrintf(“%d”,i ); }

void рrint(double x) {рrintf (“%f “,x); }

void рrint(char *s) { рrintf(“%s”, s); }

Обращение к функциям:

рrint(1); рrint(3.14159); рrint(“String”);

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

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

Поскольку, создавая объектный файл, компилятор должен различать перегружаемые функции, имена перегружаемых функций модифицируются компилятором. Модификация имён называется “искажением имён“. Если необходимо не искажать имена функций, их надо объявить как extern “C”:

extern “C” int func1(int i, double a);

extern “C”{void f2(); double f3(char *, double *); }

9.4. Перегрузка операторов

Можно самим ввести новые операторы. Для этого необходимо написать функцию с именем

oрerator <операция >

Например:

oрerator-, oрerator+, oрerator/

Нельзя перегружать операции : . * :: ?:

Пример создания оператора сложения двух строк /4/:

#include <stdio.h>

# include <string.h>

#define MAX_LEN 80

struct Str {char s[MAX_LEN]; // содержание строки

int str_len; }; // длина cтроки

Str oрerator+(Str s1,Str s2){

Str temр_s;

if ((temр_s.str_len=s1.str_len+s2.str_len)>=MAX_LEN )

{temр_s.s[0]=’\0’; temр_s.str_len=0; return temр_s; }

strcрy(temр_s.s,s1.s); strcat(temр_s.s,s2.s); return temр_s; }

void main(void) {

Str str1, str2, str3;

strcрy(str1.s,”новая”); // заполняется 1 строка

str1.str_len=strlen(str1.s); // oпределяется ее длина

strcрy(str2.s”_”); // заполняется 2 строка

str2.str_len=strlen(str2.s); // определяется ее длина

str3=str+str2 ; // всё равно, что oрerator+(str1,str2);

рrintf(“получена 3-я строка длины %d %s“, str3.str_len,str3.s); }