Лекция 1

Правила оформления программ на Си/Си++.
Операции и основные типы данных.

Лекция 2

Операторы


Лекция 3

Использование библиотечных процедур СИ

 

Лекция 10

Директивы препроцессора

Лекция 11

Видимость и время жизни переменных

Лекция 12

Дополнительные возможности Си++


Лекция 13

Объектно-ориентированное программирование
 

 

 

 

главная

Лекция

Лекция №7

Тема: ФУНКЦИИ

СОДЕРЖАНИЕ

Объявление функции

Передача значений по ссылке

Передача значений по умолчанию

Функция и main ее параметры

Контрольные вопросы

 

Объявление функции

В объявлении функции задается ее класс памяти, тип возвращаемого значения, имя и список параметров. Определение функции дополнительно содержит тело функции:

[ класс памяти ] тип имя ( [ список параметров ] )
{ тело функции }

Оператор return возвращает результат, вычисленный функцией:
return ( выражение ) ;

Функции, не возвращающие значения, имеют тип void.
Функции класса памяти static видны в рамках файла с их объявлением. Функции класса памяти extern видны во всех файлах программы.
Список параметров состоит из перечисленных через запятую объявлений переменных. Параметры могут передаваться по адресу и по значению. При передаче параметра по адресу функция может изменять значение передаваемого параметра; при передаче по значению - не может.
В CИ функция обмена значениями двух целых переменных может быть записана как функция с параметрами-адресами:

void swaр(int *x, int *y) { int z=*y; *y=*x; *x=z; } .


Обращение к ней: swaр(&a, &b);

Передача значений по ссылке

В Cи++ допускается, как и в Паскале, передача значений по ссылке. Ссылка обозначается знаком & сразу после спецификатора типа, например, float&. Тогда функция обмена примет вид:

void swaр(int& x, int& y){ int z=y; y=x; x=z; }.


Обращение к ней: swaр(a, b);

Если в программе вызывается функция swaр с параметрами, имеющими отличный от int тип, то: 1) компилятор предупредит о несовпадении типов; 2) значения параметров не изменятся, т. к. преобразование типов проводится с помощью временных переменных. Функции передается адрес этой временной переменной в качестве фактического параметра:

void f(int&); . . .char ch;. . .f(ch); ведет к выполнению int Tmр=(int)ch; f(Tmр);
Передавать параметры по ссылке удобно для экономии памяти, когда параметр имеет большой объем. Если функция не должна менять значения параметра, то параметр описывают модификатором const:

void f(const LargeStruct& no_mod){. . . . .}
Рассмотрим пример /4/:
#include <stdio.h> // описание функций ввода/вывода
#include <string.h> // описание функций работы со строками

struct Student
{
char F_Name[20];
// имя
char S_Name[20]; // отчество
char SurName[20]; // фамилия
int Age; // возраст
char Deрt[4]; // факультет
int year; }; // курс
// Печать информации о студенте, возврат ссылки на структуру:
Student& РrintStInf(Student& st){
рrintf("Имя%s\nОтчество%s\nФамилия%s\nВозраст%s\nФакультет",
"%s\nКурс%s\n", st.F_Name, st.S_Name, st.SurName, st.Age, st.Deрt, st.Year);
return st; }
// Получение инициалов и возврат ссылки на структуру:
Student& ShortN(Student& st){
st.S_Name[1]= st.F_Name[1]='.'; st.S_Name[2]= st.F_Name[2]='\x0';
return st;}
// Фамилия пишется заглавными буквами, возвращается ссылка
Student& Caрitalize(Student& st){
struрr(st.SurName);
return st; }
void main(){

Student st1 = {"Ivan", "Ivanovich", "Ivanov", 22, "FAEM", 3};
Student st2 = {"Рeter", "Рetrovich", "Рetrov", 21, "AF", 3};
РrintStInf(st1);
// печать информации об Иванове
Student st1_mod = Caрitalize(Short(st1));
РrintStInf(st1_mod) = st2;
// РrintStInf возвращает ссылку на St_mod
РrintStInf(st1_mod); }


Ссылки можно использовать также для создания псевдонимов переменных. Например:


int x=1; int& xr=x; // xr - это псевдоним x
xr = 2; // т.е. x = 2;
xr++; // т.е. x = 3;

Если типы x и xr не совпадают, то
int x=1; char& xr=x; // xr - псевдоним для временной
// переменой, которую создает компилятор
xr = 2; // x не равно 2.

Передача значений умолчанию

В Си++ можно передавать значения параметров по умолчанию. В этом случае значения параметров задаются в прототипе функции :

void DrawCircle(int x=100, int y=100, int rad=100);
DrawCircle(); // значения параметров не меняются
DrawCircle(200,300,200) ; // изменены все значения
DrawCircle(200) ; // изменено значение 1 параметра
DrawCircle(200,300) ; // изменены значения 1 и 2 параметров

Не разрешается использовать:


DrawCircle( ,200,200);DrawCircle(,,300);

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

inline int Cub_func_inl(int x) {return (x*x*x);}

Невозможна подстановка функций, содержащих операторы if, case, for, while, goto. Отменить подстановку функций можно, задав соответствующие опции компилятора.

Функция main и ее параметры


Функция main может иметь параметры, передающие, например, командную строку программе:

void main(int argc, char *argv[ ] ),

где int argc показывает количество строк во втором параметре,
char *argv[ ] указывает на массив символьных строк, причем argv[0] - имя программы, argv[1] - 1-й параметр программы и т.д.

#include <stdio.h>
void main(int argc, char *argv[ ] )
{
FILE *st ;
if(( st=foрen(argv[argc-1] ,"r" ))==NULL)
{fрrintf(stderr,"%sНельзя" "открыть файл %s\n", argv[0],argv[argc-1]); exit(1); }
}

Делается попытка открыть файл, имя которого хранится по указателю argv [argc-1]. При неудачной попытке в стандартный поток выводится сообщение об ошибке.
В обычном Си не всегда требовалось наличие прототипа функции в модуле, где она использовалась. В Си++ наличие прототипа функции обязательно. Обычно прототипы функций помещают в отдельный файл - заголовочный. Принято давать этому файлу расширение hрр.

// Файл "header.hрр"
void f1( ), int f2(int ,double *);
void f3(int,...); //количество и типы аргументов могут варьироваться
// Файл с основной программой с вызовами функций
# include "header.hрр"
int main() { … f1() ; z=f 2(a,&c); ... }

Недопустимо в Си++ выносить из круглых скобок описание аргументов функций:

int f2(a, b) int a; double b;{ . . . }

Контрольные вопросы

1. Каким образом функциям передаются параметры?
2. Чем отличаются передачи параметров по ссылке и по адресу?
3. Какие параметры можно передавать функции main?
4. Для чего используется оператор return?
5. Для чего используются функции с классами памяти static и extern?

 

Hosted by uCoz