Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Praktikum_programmirovanie / Praktikum_programmirovanie.doc
Скачиваний:
65
Добавлен:
30.03.2015
Размер:
15.88 Mб
Скачать

Лабораторная работа №5

Функции и многомерные массивы в С++

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

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

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

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

[ класс ] тип имя ( [ список параметров ])[throw ( исключения ) ]

{ тело функции }

В квадратных скобках указана необязательная часть.

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

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

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

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

Например вызов функции ожидания нажатия произвольной клавиши на клавиатуре - функция getch(), объявление которой находится в библиотеке conio.h, можно произвести следующим образом

....

getch();

....

Существует несколько способов возврата управления к точке, из которой была вызвана функция:

  • Если функция не должна возвращать результат, управление возвращается либо просто при достижении правой фигурной скобки, завершающей функцию, либо

  • При выполнении оператора return.

Если функция должна возвращать результат, то оператор

  • return выражение;

возвращает значение выражение в обращение к функции. Таким образом, оператор возврата имеет две формы:

return;

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

return выражение;

Например:

return; не возвращает значения;

return 3; возвращаемое значение = 3;

return (a + b); возвращаемое значение = значению выражения (а + b);

Пример определения функции

#include<iostream.h>

#include<conio.h>

double cube(double x) //объявление функции – заголовок. Функция cube возводит в 3 степень вещественное число х, возвращает результат вещественного типа

{

return x*x*x; //возвращает в основную программу х в 3 степени

}

int main()

{

double x,y;

cout<<"Input x = ";

cin>>x; //ввод с клавиатуры числа х

y=1+cube(x); //вызов функции cube

cout<<y; //вывод результата

getch();

}

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

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

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

Пример

#include<iostream.h>

#include<conio.h>

int fun(int х,int у)

{

return(х+у);

}

int main()

{

int a=1,b=9,c=2.5;

cout<<fun(a,c); несоответствие типов, результат будет 3, с - округлится

/*cout<<fun(a,b,c);*/ будет ошибка

getch();

}

Пример

#include<iostream.h>

#include<conio.h>

int fun(int x,char y)

{ cout<<"y="<<y<<'\n'; вторая переменная просто проигнорируется

int fun(int x, double y) – даст верный результат

return(x+y);

}

int main()

{

int a=2,b=100000000,c=2.5;

cout<<fun(a,b);

getch();

}

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

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

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

Результат работы программы:

i j k

1 2 3

1 3 4

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

Передача массива в функцию

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

• массив нельзя скопировать,

• имя массива при использовании автоматически преобразуется в указатель на его первый элемент.

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

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

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

#include<iostream.h>

#include<conio.h>

void mod_arr(int *a, int n) или void mod_arr(int a[], int n)

{

………

}

int main()

{

int i; int b[2]={1,2};

mod_arr(b,2);

……

}

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

Отметим, что на самом деле в языке C++ не существует никаких многомерных массивов. Фактически вместо многомерных массивов используется массив массивов.

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

#include<iostream.h>

#include<conio.h>

void matrix(int (*a)[2],int n,int m)

{

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

{for(int j=0;j<m;j++)

cout<<a[i][j]<<'\t';

cout<<'\n';}

}

int main()

{

int i;

int c[2][2]={{2,1},{3,5}};

matrix(c,2,2);

getch();

}

НЕЛЬЗЯ!

void matrix(int *a[2],int n,int m) - массив из 2 указателей

void matrix(int (a*)[2],int n,int m) - Здесь параметр а объявлен как указатель на массив из 2 целочисленных элементов

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

void matrix(int a[][2],int n,int m)

первый параметр является массивом, элементы которого представляют собой массивы из 2 целочисленных элементов

Строки

В С++ существует 2 типа строк. Первый из них - это массив переменных типа char.

Пример:

char name[50];

cin>>name;

cout<<"Hello "<<name;

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

Прототип функции

Краткое

описание

Примечание

unsigned strlen(const char* s);

Вычисляет длину строки s.

int strcmp(const char* s1, const char* s2);

Сравнивает строки s1 и s2.

Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 – результат положительный.

int strcnmp(const char* s1, const char* s2);

Сравнивает первые n символов строк s1 и s2.

Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 – результат положительный.

char* strcpy(char* s1, const char* s2);

Копирует символы строки s1 в строку s2.

char* strncpy(char* s1, const char* s2, int n);

Копирует n символов строки s1 в строку s2.

Конец строки отбрасывается или дополняется пробелами.

char* strcat(char* s1, const char* s2);

Приписывает строку s2 к строке s1

char* strncat(char* s1, const char* s2);

Приписывает первые n символов строки s2 к строке s1

char* strdup(const char* s);

Выделяет память и переносит в нее копию строки s

При выделении памяти используются функции

cin и cout являются объектами (переменными) классов istream и ostream, которые определены в заголовочном файле iostream.h. А если так, они предоставляют функции, которые ваши программы могут вызывать для решения определенных задач. Так, функции cin.get и cout.put позволяют вашим программам вводить или выводить один символ.

Функция cin.getline позволяет программам читать строку текста с клавиатуры.

Пример

#include <iostream.h>

int main()

{

char string[128];

cout << "Введите строку текста и нажмите Enter";

cin.getline(string, sizeof(string), 'Я');

cout << "Вы ввели: " << string;

}

Второй из вариантов, более удобный - это специальный класс string. Для его работы необходимо в начале программы подключить заголовочный файл string.h:

#include <string>

Для создания строки вам необходимо в начале программы написать using namespace std;

Теперь чтоб создать строку достаточно написать:

string s;

Для записи в строку можно использовать оператор =

s="Hello";

Пример работы с классом string:

string name;

cout<<"Enter your name;

cin>>name;

cout<<"Hi "<<s<<"!";

Следует помнить, что считывание будет происходить до первого пробела, остальные символы будут отбрасываться.

Если нужно считать строку со всеми пробелами, то необходимо использовать функцию getline следующим образом:

     string S;      getline(cin,S);

Функции для работы со строками string:

s.append(str) - добавляет в конец строки строку str. Можно писать как s.append(переменная), так и s.append("строка");

s.assign(str) - присваивает строке s значение строки str. Аналогично записи s=str;

int i=s.begin() - записывает в i индекс первого элемента строки

int i=s.end() - аналогично, но последнего

s.clear() - как следует из названия, отчищает строку. Т.е. удаляет все элементы в ней

s.compare(str) -сравнивает строку s со строкой str и возвращает 0 в случае совпадение (на самом деле сравнивает коды символов и возвращает из разность)

s.copy(куда, сколько, начиная с какого) - копирует из строки s в куда (там может быть как строка типа стринг, так и строка типа char). Последние 2 параметра не обязательные (можно использовать функцию с 1,2 или 3 параметрами)

bool b=s.empty() - если строка пуста, возвращает true, иначе false

s.erase(откуда, сколько) удаляет n элементов с заданной позиции

s.find(str,позиция) - ищет строку str начиная с заданной позиции

s.insert(позиция,str, начиная, beg, count) - вставляет в строку s начиная с заданной позиции часть строки str начиная с позиции beg и вставляя count символов

int len=s.length() - записывает в len длинну строки

s.push_back(symbol) - добавляет в конец строки символ

s.replace(index, n,str) - берет n первых символов из str и заменяет символы строки s на них, начиная с позиции index

str=s.substr(n,m) - возвращает m символов начиная с позиции n

s.swap(str) меняет содержимое s и str местами.

s.size() - возвращает число элементов в строке.

Передача строк

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

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

Как вы уже знаете, функции C++ часто используют символ NULL для определения конца строки. Следующая программа создает функцию с именем string_length, которая ищет символ NULL в строке для определения количества символов, содержащихся в строке. Далее функция использует оператор return для возврата длины строки вызвавшей функции. Программа передает несколько различных символьных строк в функцию, отображая длину каждой из них на экране:

#include<iostream.h>

#include<conio.h>

int string_length(char string[])

{ int i;

for (i = 0; string[i] != '\0'; i++);

return(i);}

int main()

{

char title[] = "I like apple";

char lesson[] = "Cat";

cout << "Строка " << title << "содержит " << string_length(title) << " символов" << endl;

cout << "Строка " << lesson << " содержит " << string_length(lesson) << " сисволов" << endl;

getch();

}