Ю. А. Медведев основы программирования на языке c++


Скачать 496.92 Kb.
НазваниеЮ. А. Медведев основы программирования на языке c++
страница4/5
ТипДокументы
1   2   3   4   5

ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ

Функция — это именованная последовательность описаний и операторов, выполняющая какое-либо законченное действие.

Программа должна иметь главную функцию main() - обеспечивает создание точки входа в объектный модуль.

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

Любая функция должна быть объявлена и определена. Объявление функции должно находиться в тексте раньше ее вызова

Объявление функции (прототип) задает её имя, тип возвращаемого значения и список передаваемых параметров.

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

Синтаксис: 

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

Класс - задает область видимости функции

  • extern — глобальная видимость во всех модулях программы (по умолчанию);

  • static — видимость только в пределах модуля, в котором определена функция.

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

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

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

Функции возвращают значение с помощью оператора return.

return [ выражение ];

Функция может содержать несколько операторов return. Если функция описана как void, выражение не указывается.

Примеры:

int fl(){return 1;} // правильно

void f2(){return 1;} // неправильно

double f3(){return 1;} // правильно. 1 преобразуется к типу double

Пример 5.1. Функция, возвращающая сумму двух целых величин:

#include

int sum2(int , int);//прототип функции, тело функции находится ниже

int main(){

int a = 2, b = 3, c, d;

с = sum(a, b); // вызов функции

cin >> d;

cout << sum(c, d); // вызов функции

return 0; }

int sum(int a, int b){ // определение функции

return (a + b);}

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

Для сохранения значений локальных переменных используется спецификатор памяти static.

Пример 5.2.

void f(int a){ int m= 0; cout << "n m p\n";

while (a--){

static int n = 0; // инициализируется только один раз

int p = 0; // локальная переменная

cout << n++ << ‘ ‘ << m++ << ‘ ‘ << p++ << ‘\n’;}}

int main(){ f(3); f(2); return 0;}

Результат:

Вызов f(3)

Вызов f(2)

n m р

0 0 0

1 1 0

2 2 0

n m р

3 0 0

4 1 0

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

Пример:

int* f(){

int а = 5; // переменная существует только внутри функции

return &а; // нельзя! }

Параметры функций

Параметры, перечисленные в заголовке описания функции, называются формальными, а записанные в операторе вызова функции — фактическими. При вызове функции формальные параметры замещаются фактическими.

Существует два способа передачи параметров в функцию: по значению и по адресу.

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

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

Пример 5.3.

/* функция увеличивает значение передаваемых параметров на единицу*/

void f(int i, int* j, int& k){ i++; (*j)++; k++;};

int main(){

int i = 1, j = 2, k = 3; // инициализируем переменные

cout <
f(i, &j, k); // i – по значению, j и k – по адресу

cout << i <<" "<< j <<" "<< k; // значения после вызова функции

return 0;}

В результате получим 1 2 3 , 1 3 4. Видно, что после вызова функции переменные переданные в функцию по адресу изменились, а по значению – нет.

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

Модификатор const, указанный перед параметром, запрещает изменение значения этого параметра внутри функции. При попытке изменения мы получим ошибку компиляции. Например, int f(const char*); Строка в C++ представляет собой массив символов и мы вынуждены передавать ее в функцию по адресу. В то же время модификатор const гарантирует, что данная строка не будет изменена.

Передача массивов в качестве параметров.

В C++ многомерный статический массив - понятие условное. Как известно, массив размерности n является одномерным массивом множества объектов производного типа - массивов размерности n-1.

Главной особенностью передачи массивов в качестве параметров является то, что объявление одномерного массива-параметра преобразуется к объявлению указателя на элемент производного типа.

Например, массив int a[10][3] сводится к указателю типа int (*)[3].

После такого приведения внутри функции ничего не известно о размере массива. Таким образом, при работе с массивами в качестве параметров следует передавать и количества элементов в размерностях либо делать эти значения глобальными константами (или определять с помощью директив препроцессора).

Пример 5.4. Передача массивов как параметров в функции сложения элементов массива.

/* функция суммирования элементов одномерного массива. Со статическими и с динамическими массивами проблем не возникает, т.к. при передаче параметра массив сводится к указателю. */

int sum1(int *a, int dim){

//int sum1(int a[], int dim){ эквивалентное описание

cout<
int s=0;

for (int i=0;i
return s;};

/* функция суммирования элементов двухмерного массива. Массив передается как указатель на тип элемента двухмерного массива. В функции используется тот факт, что элементы в памяти расположены подряд */

int sum2_v1(int *a, int dim1, int dim2){ // передаем количества элементов

int s=0;

for (int i=0; i
for (int j=0; j
s+=a[i*dim2+j]; // рассматриваем двухмерный массив как одномерный

return s;}

/* функция суммирования элементов двухмерного массива. Массив передается как указатель на указатель на тип элемента массива. Подходит для динамических массивов. */

int sum2_v2(int ** a, int dim1, int dim2){

int s=0;

for (int i=0; i
for (int j=0; j
s+=a[i][j]; /* поскольку имеем указатель на указатель, можем пользоваться двойными индексами */

return s;}

/* функция суммирования элементов статического двухмерного массива либо динамического массива, где динамически задавалось количество элементов только в первой размерности. Массив передается как указатель на массив из 3-х элементов. Тройка в int a[][3] не задает количество элементов (его передаем отдельным параметром) а лишь определяет тип. */

int sum2_v3(int a[][3], int dim1, int dim2){

int s=0;

for (int i=0; i
for (int j=0; j
s+=a[i][j];

return s;}

/* функция аналогичная предыдущей, но тип параметра другой */

int sum2_v4(int a[][10], int dim1, int dim2){return 0;}

int main(){

int A[5]={1,2,3,4,5}; // статический одномерный массив

int B[2][3]={{1,2,3},{4,5,6}}; // статический двухмерный массив

int *C=new int [4]; /* двухмерный, динамически задается только количество элементов в первой размерности */

for (int i=1; i<=4;i++) C[i-1]=i; // инициализируем массив C

int ** D= new int* [3]; // двухмерный полностью динамический массив

for (int i=0;i<3;i++) D[i]=new int [4]; // инициализируем массив D

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

for (int j=0;j<4;j++) D[i][j]=i*4+j+1;

cout<
cout << sum1(A,sizeof(A)/sizeof(A[0]))<
cout << sum1(C,4)<
/* сводим двухмерный статический к одномерному */

cout << sum2_v1(&B[0][0],2,3)<
cout << sum2_v1((int *)B,2,3)<
//cout << sum2_v2(B,2,3)<
cout << sum2_v3(B,2,3)<
//cout << sum2_v4(B,2,3)<
cout << sum2_v2(D,3,4)<
//cout << sum2(D[0],3,4)<
delete [] C; // освобождаем память из под одномерного массива C

for (int i=0;i<3;i++) delete [] D[i]; // освобождаем память из под D

delete [] D;

return 0;}

Описанные способы работы с массивами в большей степени присущи стилю программирования на языке C. В С++ для работы с массивами рекомендуется использовать контейнер vector из стандартной библиотеки шаблонов (STL).

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

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

тип (*имя_указателя) (список типов принимаемых параметров);

Пример:

void f(int а ){…}  определение функции, принимающий один целочисленный параметр.

void (*pf)(int);  указатель на функцию, принимающую целочисленный параметр

pf = f;  указателю присваивается адрес функции

pf(10);  вызываем функцию f, через ее адрес и с аргументом равным десяти.

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

Пример 5.5.

int add (int a,int b){return a+b;} //функция сложения двух чисел

int sub (int a,int b){return a-b;} //функция вычитания двух чисел

int mul (int a,int b){return a*b;} //функция умножения двух чисел

typedef int (*op)(int, int); /* определяем новый тип - указатель на функцию, принимающую два целых параметра и возвращающую целый результат */

enum oper {plus, minus, production}; // определим набор операций

int main(){

op doit[]={&add,&sub,&mul}; // массив из указателей на функции

int a,b;

cin>>a>>b; // вводим два числа

oper action; // переменная определяет действие над числами

/* вводим тип операции */

action = production;

cout << doit[action](a,b); /* в зависимости от значения параметра action произойдет вызов необходимой функции */

return 0;}

Данный подход избавляет нас от использования конструкций if и switch при выборе той или иной функции.

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

Пример 5.6.

/*определим функцию, возвращающую максимальный элемент в массиве */

int max_array(int * a, int dim){ int max=a[0];

for(int i=1;i
return max; }

/* определим функцию, возвращающую сумму элементов массива */

int sum_array(int * a, int dim){int s=0; for(int i=0;i
return s; }

typedef int (* funct)(int *, int); // определим тип указателя на семейство функций

// функция увеличивающая некоторую характеристику массива в три раза

int array_param_3x(int *a, int dim, funct f){ return 3*f(a,dim); }

int main(){

int a[]={4,2,7,5,3};

// выводим утроенное значение максимального элемента

cout << array_param_3x(a,sizeof(a)/sizeof(a[0]), &max_array)<
// выводим утроенное значение суммы элементов

cout << array_param_3x(a,sizeof(a)/sizeof(a[0]), &sum_array)<
return 0;}

СЕМИНАРСКОЕ ЗАНЯТИЕ 1

Студент самостоятельно должен изучить следующий материал: Понятие среды разработки и её составные части. Понятие транслятора. Компиляторы, интерпретаторы, JIT- компиляторы, байт код. Компилятор C++. Понятие линковщика. Понятие препроцессора. Проект на C++. Файлы библиотек. Заголовочные файлы. Основные библиотеки, входящие в стандарт C++, их заголовочные файлы.

Задания к семинарскому занятию:

  1. Чему эквивалентна запись j=++i; ?

  2. Чему эквивалентна запись j=i++; ?

  3. Пусть i=j=1; Чему будут равны значения переменных при выполнении следующих операций:

    1. num=i++;

    2. num=(++i)++;

    3. num=++j+i++;

    4. num=(j++)+i++;

    5. num=i++;

    6. num=(++i)++;

    1. num=++j+i++;

    2. num=(j++)+i++;

    3. num=j+++i++;

    4. num=j+(++i)++;

    5. num=(++j)+++i++;

  4. Найти значения выражений:

  1. 10 \ 2 + 10 % 3=?

  2. 13.2 – 10\4 – 20.1\7*2=?

  1. ~((13<<2)| 21 ^ 10) =?

  2. ((10==12)&&((4<3)||(7>=5))^16)=?

СЕМИНАРСКОЕ ЗАНЯТИЕ 2

Студент самостоятельно должен изучить следующий материал: Структура программы на C++. Основные функции модуля ctime (time.h). Функции модуля cmath. Тригонометрические функции. Функции округления. Вычисление логарифма и экспоненты. Случайные числа. Вычисление корня, возведение в степень, абсолютное значение числа, вычисление остатка от деления вещественных чисел.
1   2   3   4   5

Похожие:

Ю. А. Медведев основы программирования на языке c++ iconЕ. Н. Акимова основы программирования на языке фортран учебное пособие
Применение многопроцессорных вычислительных систем (мвс) ставит две задачи построения параллельных алгоритмов: распараллеливание...

Ю. А. Медведев основы программирования на языке c++ iconТоп-программа «Разработчик 1С» примерная программа дисциплины
Основы программирования и конфигурирования в корпоративных информационных системах

Ю. А. Медведев основы программирования на языке c++ iconВопросы к зачету по дисциплине Основы программирования
Описать основные элементы структуры программы ( Раздел интерфейса, раздел реализации, раздел инициализации)

Ю. А. Медведев основы программирования на языке c++ iconОсновы программирования
Цель контрольной работы – закрепление и проверка знаний, полученных студентами заочной формы обучения в процессе самостоятельного...

Ю. А. Медведев основы программирования на языке c++ iconПаскаль как язык структурно-ориентированного программирования
Виртом в 1971 г., играет особую роль и в практическом программировании, и в его изучении. С непревзойденной четкостью в нем реализованы...

Ю. А. Медведев основы программирования на языке c++ iconМетодические указания содержат общие понятие объектно-ориентированного...
Методические указания предназначены для выполнения курсовой работы по дисциплине «Объектно-ориентированное программирование» для...

Ю. А. Медведев основы программирования на языке c++ iconМетодические указания по выполнению лабораторных работ на алгоритмическом...
Хотя набор стандартных функций электронных таблиц достаточно широк, для некоторых задач он либо недостаточен, либо выполнение таких...

Ю. А. Медведев основы программирования на языке c++ iconЛабораторная работа №1: Интерфейс среды matlab и основы программирования....
Интерфейс среды matlab (окно команд, окно рабочего пространства, окно истории команд, окно «текущая папка», окно Details, меню Start,...

Ю. А. Медведев основы программирования на языке c++ iconВведение в науку о языке
Назовите основные разделы науки о языке и единицы языка, изучаемые в этих разделах

Ю. А. Медведев основы программирования на языке c++ iconРуководство для заявителей
Представительством Европейского Союза в России для облегчения понимания правил конкурса для потенциальных российских участников....

Вы можете разместить ссылку на наш сайт:


Все бланки и формы на filling-form.ru




При копировании материала укажите ссылку © 2019
контакты
filling-form.ru

Поиск