Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Лекция 16. Передача аргументов функции





Передача аргументов функции

 

В языках программирования обычно реализуют два способа передачи аргументов функции: по значению и по ссылке.

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

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

Рассмотрим эти способы на примерах.

 

// Передача аргумента по значению.

#include <iostream.h>

int f (int x);

void main()

{ int arg = 10.0;

cout << “Значение функции f(arg) = “ << f(arg) << “\n”;

cout << “Значение аргумента arg = “ << arg << “\n”;

}

int f(int x)

{ x = 2*x;

return x;

}

 

Результат:

Значение функции f(arg) = 20

Значение аргумента arg = 10

 

В этом примере аргумент argсохранил своё значение при выходе из функции f().

Для организации передачи аргумента по ссылке используется ссылочный формальный параметр, который объявляется в заголовке функции с помощью знака ‘&’.

 

//Передача аргумента по ссылке

#include <iostream.h>

void f (int &i) // &i – ссылочный прараметр

{ i = 10; }

// Значение 10 присваивается переменной, на которую ссылается i

void main()

{ int value = 1;

cout << “Исходное значение value:” << value << ‘\n’;

f (value); // передаем адрес переменной value

cout << “Новое значение value:” << value << ‘\n’;

}

 

Результат:

Исходное значение value: 1

Новое значение value: 10

 

Замечания.

1. В теле функции ссылочный параметр используется непосредственно, без ‘*’. i=10;эквивалентно по смыслу*i = 10;

2. При вызове функции аргумент записывается без знака ‘&’. f(value);эквивалентнопо смыслуf(&value);

Функция может возвращать ссылку в качестве результата. Это означает, что она возвращает неявный указатель на значение, передаваемое ею в операторе return.

Пример.

 

# include <iostream.h>

int & f(); // возвращает ссылку на целое число

int value = 100; // глобальная переменная

void main()

{ cout << f() << ‘\n’;

/* вывести на экран значение, записанное по адресу, возвращаемому

функцией f() */

int x;

x = f();

/* переменной х присвоить значение по ссылке, которую возвращает

функция f() */

f() = 200;

/* по адресу, возвращаемому функцией f(), записать

значение 200 */

cout << f() << ‘\n’;

}

int &f()

{ return value; } // возвращает ссылку на value

 

Результат:

 

Замечание.

Нельзя возвращать ссылку на локальную переменную.

 

Например:

 

int &f()

{ int i = 10;

return i; } // ошибка

 

При завершении функции переменная i выйдет за пределы видимости и ссылка на неё будет не определена.

 

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

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

Перегруженные функции должны отличаться типами и (или) числом параметров.

Рассмотрим пример.

 

# include <iostream.h>

void f(int i); // один целочисленный параметр

void f(int i, int j); // два целочисленных параметра.

void f(double k); // один параметр типа double

void main()

{ f(10); // вызов f(int)

f(10,20); // вызов f(int,int)

f(12.23); // вызов f(double)

}

void f(int i)

{ cout << “В функции f(int), i=” << i << ‘\n’;}

void f(int i, int j)

{ cout << “В функции f(int, int), i=” << i;

cout << “, j=” << j << ‘\n’;}

void f(double k)

{ cout << “В функции f(double), k=” << k << ‘\n’;}

 

Результат:

В функции f(int), i=10

В функции f(int,int), i=10, j=20

В функции f(double), k=12.23

 

В этом примере функция f() перегружается три раза. Компилятор обладает достаточной информацией, чтобы вызвать правильную версию функции.

В С++ предусмотрено автоматическое преобразование типов при перегрузке функций.

Например:

 

# include <iostream.h>

void f(int x);

void f(double x);


void main()

{ int i = 10;

double d = 10.1;

short s = 99;

float r = 11.5F;

f(i); // вызов версии f(int)

f(d); // вызов версии f(double)

// далее автоматическое преобразование типов

f(s); // short => int и вызов f(int)

f(r); // float => double и вызов f(double)

}

void f(int x) {

cout << “В функции f(int): “ << x << “\n”;}

void f(double x) {

cout << “В функции f(double): “ << x << “\n”;}

 

Результат:

В функции f(int): 10

В функции f(double): 10.1

В функции f(int): 99

В функции f(double): 11.5

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

Аргументы, передаваемые функции по умолчанию

 

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

Пример.

 

# include <iostream.h>

void myfunc(int x=0, int y=0);

void main()

{ myfunc(1,2);

myfunc(10);

mufunc();

}

void myfunc (int x, int y)

{ cout << “x=” << x << “,y=” << y << “\n”;}

 

Результат

x=1, y=2

x=10, y=100

x=0, y=100

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

void f(int a = 1, int b); // неверно

 

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

Значения, передаваемые по умолчанию, должны быть заданы только один раз и причем при первом объявлении функции.

Передача аргументов по умолчанию применяется при перегрузке функций.

Пример.

Определим две версии стандартной функции strcat(): одна будет присоединять всё содержимое одной строки к концу другой, а вторая функция использует один аргумент – количество присоединяемых символов:

 

void mystrcat(char *s1, char *s2, int len);

void mystrcat(char *s1, char *s2);

 

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

 

# include <iostream.h>

# include <string.h>

void mystrcat(char *s1, char *s2, int len=0);

void main()

{ char str1[80]=”Это тест. ”;

char str2[80]=”’0123456789”;

mystrcat(str1,str2,5);

cout << str1 << ‘\n’;

strcpy(str1,”Это тест. ”);

mystrcat(str1,str2); // присоединяем всю строку, поскольку len=0

cout << str1 << ‘\n’;

}

void mystrcat(char *s1, char *s2, int len)

{ while (*s1) s1++; //находим конец строки

if (len == 0) len = strlen(s2);

while (*s2 && len) {

*s1 = *s2; // копируем символы

s1++;

s2++;

len --;

}

*s1=’0\’; // добавляем нулевой байт

}

 

Результат

Это тест.01234

Это тест.0123456789

Вопросы

1.Для организации передачи аргумента по ссылке используется параметр

1.&;

2.*.

2.Перегруженные функции могут отличаться числом параметров

1.да;

2.нет.

3.Функция может возвращать ссылку на глобальную переменную

1.да;

2.нет.

 

 

Лекция 17

 

Ввод-вывод в языке С++


 

В языке С++ отсутствуют встроенные средства ввода-вывода. В связи с этим к программе необходимо подключать библиотеку ввода-вывода. с помощью директивы

# include <iostream.h>

При выполнении операции ввода осуществляется преобразование сигналов от клавиатуры в двоичные коды внутреннего представления данных. Операция вывода данных на экран дисплея выполняет преобразование двоичных кодов в символы.

Операция ввода на языке С++ имеет следующий формат:

сin >> <имя объекта базового типа>;

К базовому типу относятся: int, long, float, double, charи др.

Операция вывода имеет следующий формат:

cout << <выражение базового типа>;

Пример.

 

....

{ int a; float b;

cin >> a;

cout << “\n a= “ << a;

cin >> b;

cout << “\n b= “ << b;

...

}

Особенности ввода и вывода данных

 

1) использование операций сдвига для ввода и вывода данных не изменяет их приоритет.

Например:

сout << 5+6*7-a;

Поскольку приоритет арифметических операций выше приоритета оператора <<, то скобки можно не использовать в операторе вывода.

 

Пример:

cout << (3+4>5);

Здесь нужны скобки, т.к. приоритет операции сравнения меньше, чем ранг оператора <<.

 

2) Для ввода последовательности значений можно использовать цепочки операций:

Например:

int i, j, k;

cin >> i >> j >> k;

3). При вводе и выводе массивов необходимо использовать циклы.

Например:

 

float a[5];

for (int i=0; i<5; i++) cin >> a[i]; // ввод

for (int i=0; i<5; i++) cout <<”\n”<< a[i]; // вывод

 

Рассмотрим особенности ввода и вывода целых чисел, вещественных чисел и строк.

4). При вводе и выводе целых чисел существует ограничение на длину внешнего и внутреннего представления.

Например:

a). long g;

cin >> g;

cout << “\n g= ” << g;

_______________________.

123456789 <enter>

Результат:

g=123456789

 

б). int i;

cin >> i;

cout << “\n i= ” << i;

.______________________

123456789 <enter>

Результат:

i = -13035 - неправильное значение

5). При вводе целых чисел их можно набирать на клавиатуре в десятичном, восьмеричном и шестнадцатеричном виде.

Например:

....

{ int a;

cin >> a;

cout << “\n a= “ << a;

}

._____________________

1).077777<enter>

a= 32767

 

2). -0x7FFF <enter>

a = -32767

 

6). При вводе вещественных чисел допустимы все их формы записи.

Например:

....

{ float pi;

cin >> pi;

cout << “\n pi= “ << pi

}

.______________________

2.1415<enter>

или

3.1415e0 <enter>

или

+3.1415e0 <enter>

или

0.3.415e+1 <enter>


 

Результат:

pi = 3.1415

7). Если вещественное значение слишком мало, то вывод происходит в экспоненциальном формате.

Например:

....

{ float t;

cin >> t;

cout << “\n t= “ << t;

}

.____________________

0.0….01 <enter>

Результат:

t = 1e-23

8). Символьная строка – массив типа char, завершающийся нулевым байтом. При вводе строки с клавиатуры набираются символы до нажатия клавиши <enter>.

Например:

char line[81];

cin >> line;

cout << line;

.______________

abcdef

Результат:

abcdef

Замечание. При вводе строки с помощью оператора >> пробел заменяется нулевым байтом.

Оператор вывода << переносит строку на экран до нулевого байта.

При выводе данных допускается их форматирование.

Вопросы

1.Задан блок

{char s[10];

cin>>s;

cout<<s;

}

При вводе строки aaaa bbb на экране появится строка

1.aaaa bbb;

2.aaaa.

 

 







Date: 2015-12-12; view: 846; Нарушение авторских прав



mydocx.ru - 2015-2024 year. (0.049 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию