![]() |
Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Объявление и определение функции ⇐ ПредыдущаяСтр 3 из 3
Объявление (прототип) функции – это описание, которое включает задание типа возвращаемого значения, имени функции и списка параметров, оторые использует компилятор для синтаксического анализа.
Определение функции дополнительно к её объявлению включает тело функции, как совокупность операторов, заключенных в фигурные скобки. Формат определения функции: Тип_возвр_знач Имя_функции(список_параметров) { операторы } Тип_возвр_знач - определяет тип значения, которое возвращается из функции. Если тип функции не указан считаются объявленными с типом int. Если функция не должна возвращать значение, она должна быть об’явлена с типом void.
Имя_функции – задает имя функции. Одно и то же имя функции может быть использовано для нескольких функций программы, такие функции называются прегружаемыми.
Список параметров – определяет параметры, которые должны передаваться в функцию при её вызове. В определении такие параметры называются формальными параметрами, поскольку они используются для формы, т.е. для возможности определить программный код функции. Для каждого элемента списка параметров указываются тип и имя параметра, элементы списка разделяются запятой.
Тип элемента необходим для проверки соответствия типов формальных и фактических параметров при вызове функции, а имя параметра для возможности ссылаться на параметры в теле функции. Функция может быть задана без параметров и вместо списка может стоять слово void.
Тело функции – это блок операторов, заключенный в фигурные скобки, определяющий выполняемые функцией действия, когда она вызывается. Для передачи управления и возврата значения из функции используется оператор return:
return выражение;
При выполнении оператора выполняются следующие действия: 1) выход из функции и возврат управления в точку её вызова; 2) вычисляется и возвращается значение выражения, указанного в операторе.
Если функция объявлена с типом void, то оператор имеет вид: return; Пример:
#include " stdafx.h" #include < iostream>
using namespace std;
bool IsCratnoe(int delimoe, int delitel); // объявление (прототип) функции
int _tmain(int argc, _TCHAR* argv[]) { int value1, value2;
cout< < " Input delimoe: "; cin> > value1; cout< < endl; cout< < " Input delitel: "; cin> > value2; cout< < endl;
// вызов функции cout< < value1< < " " < < (IsCratnoe(value1, value2)? " cratnoe ": " ne cratnoe " )< < value2;
return 0; }
bool IsCratnoe(int delimoe, int delitel) // обпределение функции { if(delimoe % delitel==0) return true; else return false; } Передача параметров в функцию
Параметры предназначены для передачи значений из вызывающей функции в вызываемую. Параметры функции являются локальными переменными функции. Областью их определения и областью видимости является блок операторов функции (тело функции).
Существует три способа передачи параметров в функцию: 1) по значению;
При передаче параметра по значению в функцию передается копия передаваемого данного. Поэтому функция не может воздействовать на само значение данного, котрое принадлежит вызывающей функции (см.пример выше).
2) по адресу (указателю);
При передаче по адресу в вызываемую функцию передается адрес размещения в памяти передаваемого данного. Поскольку становится доступным адрес, используя его вызываемая функция может изменить значение передаваемого данного. Пример: #include " stdafx.h" #include < iostream>
using namespace std;
int DrobnoeCeloe(float src, float* drob); // объявление (прототип) функции
int _tmain(int argc, _TCHAR* argv[]) { int celoe; float value, drobnoe;
cout< < " Input value: "; cin> > value; cout< < endl; celoe=DrobnoeCeloe(value, & drobnoe);
cout< < value< < " = " < < celoe< < " + " < < drobnoe;
return 0; }
int DrobnoeCeloe(float src, float* drob) // обпределение функции { int celoe=(int)src; // получаем целую часть операцией приведения типа
*drob=src-celoe; // вычисляем дробную часть и //записываем результат по указателю drob return celoe; // возвращаем целую часть } 3) по ссылке. (не давать) Составные типы данных
Для решения сложных задач, с которыми обачно сталкивается человек рассмотренных выше элементарных типов недостаточно. Они очень просты (элементарны) по сравнению с объектами реального мира. Поэтому эти типы используются как базовые типы данных, на основе которых могут быть организованы более сложные, которые так и называют – сложные типы данных. К сложным типам данных относятся: - массивы; - строки; - структуры; - классы. Язык С++ позволяет использовать эти типы для организации своих пользовательских типов. Кроме того, использование в сочетании типа указателя и динамического выделения памяти предоставляет программисту возможности формирования так называемых динамических структур данных.
Одномерные массивы
Массив — это набор данных одного типа, которые в памяти размещаются последовательно. Как работать с массивами, что можно что нельзя: 1. Определение количества элементов массива.
При объявлении массива инициализацией программист не задает явно размер массива, а он необходим для организации обработки массива, поскольку нужно знать сколько элементов хранит массив. Как это сделать? Пример: #include " stdafx.h" #include < iostream> using namespace std;
int _tmain(int argc, _TCHAR* argv[]) { float float_array[]={ 1.1f, 1.2f, 1.3f, 1.4f, 1.5f };
// определение кол-ва элементов массива int num=sizeof(float_array)/sizeof(float);
// sizeof(float_array) возвращает кол-во байт памяти, связанное с массивом cout< < " sizeof(float_array)=" < < sizeof(float_array)< < endl;
// sizeof(float) возвращает кол-во байт памяти, используемое для // представления в памяти данного типа float cout< < " sizeof(float)=" < < sizeof(float)< < endl;
cout< < " num=" < < num< < endl;
// используем значение num для распечатки элементов массива for(int i=0; i< num; i++) cout< < " float_array[" < < i< < " ]=" < < float_array[i]< < endl;
return 0; } Обычные массивы для работы предоставляют ограниченный набор средств: - нельзя присвоить одну переменную-массив другой; - недопустимо сравнивать массивы; - нельзя складывать, умножать и т. д. Единственное, что можно делать с массивами — передавать их функции как аргумент. Таким образом, чтобы присвоить один массив другому, сравнить два массива и т.д., придется написать собственный код или использовать библиотеку функций, если такая есть. Все операции можно выполнять только с отдельными элементами массива. При копировании одного массива в другой достаточно скопировать по отдельности каждый элемент массива. При сравнении массивов сравниваются соответствующие элементы. В этих операциях на отдельные элементы массива ссылаются с помощью с операции индекса, как это было показано в примерах. Если float float_array[10]; - это массив, то float_array[i] – это склаярная величина, т.е. элементарное данное, с которой можно все делать, что допустимо в данном случае на переменной типа float. Т.е. допустимы, например, такие действия как: float_array[i]=20.7; float_array[i+2]= float_array[i]*10; С++ интерпретирует квадратные скобки [] - как операцию, а не просто как обозначение элемента. Эта операция имеет высокий приоритет. Она называется операцией доступа по индексу. Слева от неё стоит операнд – имя массива, а в скобках операнд – индекс массива, к которому осуществляется доступ. В качестве индекса может применяться любое числовое выражение целого типа. Программист не может произвольно выбирать диапазон значений индексов массивов. В С++ индекс массива может лежать от значения 0 до значение nun-1, если num – это количество элементов в массиве. Но, необходимо помнить, что проверка индекса на допустимость в операции доступа по индексу не осуществляется ни на этапе компиляции, ни на этапе выполнения. Причина: разработчики компилятора С++ отказались от этого для обеспечения лучшего быстродействия разрабатываемых программ. Если программа написана так, что индекс при обращении к массиву всегда имеет допустимоё значение, то проверка не нужна. В любом случае решение принимает программист. Но, если индекс, указываемый в операторе, может выходить за пределы допустимого диапазона индексов, то программа будет работать не верно. И при отладке программы это надо помнить. Пример: #include " stdafx.h" #include < iostream> using namespace std;
int _tmain(int argc, _TCHAR* argv[]) {// как работать с массивами
float float_array[]={ 1.1f, 1.2f, 1.3f, 1.4f, 1.5f };
float new_array[10];
// копируем массив float_array в new_array
for(int i=0; i< 10; i++) //ошибка-кол-во элементов в мас. float_array =5 new_array[i]=float_array[i];
// выводим новый массив for(int i=0; i< 10; i++) cout< < " new_array[" < < i< < " ]=" < < new_array[i]< < endl;
return 0; } Вот что выведет программа. Видно, что скопированы 5 элементов из исходного массива, а остальные 5 скопированы из памяти, которая не принадлежит исходному массиву, это шум. Если вы ошиблись в индексе при доступе к элементу массива на чтение, вы не сразу обнаружите ошибку, пока не займетесь тщательным тестированием программы. Если вы ошиблись при выполнении операции записи, вы наверняка повредите данные переменных, в чью область вы попали! В этом случае правильным решением будет, например такое: #include " stdafx.h" #include < iostream> using namespace std;
int _tmain(int argc, _TCHAR* argv[]) {// как работать с массивами
float float_array[]={ 1.1f, 1.2f, 1.3f, 1.4f, 1.5f }; float new_array[10];
// копируем массив float_array в new_array for(int i=0; i< 10; i++) if (i< sizeof(float_array)/sizeof(float)) new_array[i]=float_array[i]; else new_array[i]=0; // выводим новый массив for(int i=0; i< 10; i++) cout< < " new_array[" < < i< < " ]=" < < new_array[i]< < endl;
return 0; }
Примеры программ для работы с одномерными массивами и указателями
Пример 1: Работа с указателем: инициализация указателя адресом, обращение по указателю. // pointers1.cpp #include " stdafx.h" #include < iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) { int x=5;
// инициализация указателя адресом переменной x int *y = & x;
// обращение к переменной по указателю *y cout< < " Znachenie po ukazatelu: " < < *y< < endl;
cout< < " adress peremennoi: " < < y< < endl;
return 0; } Пример 2: Выделение памяти для переменной-указателя. Присваивание значения переменной, используя указатель. #include " stdafx.h" #include < iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) { // указатель на переменную целого типа int *y; // выделение участка динамической памяти размером sizeof(int) y = new int; // присвоение значения переменной по указателю *y=10;
cout< < " y= " < < y< < endl; cout< < " *y= " < < *y< < endl;
// освобождение памяти delete y;
return 0; } Пример 3: Вычислить среднее арифметическое 10 элементов одномерного массива. 3а #include " stdafx.h" #include < iostream>
using namespace std;
// объвление функций // функция для ввода чисел массива void Input(int* a, int N); // функция для вычисления среднего арифметического для заданного массива float Average(int* a, int N);
int _tmain(int argc, _TCHAR* argv[]) { // выделение памяти массивом из 10 символов int ar[10];
// ввод массива Input (ar, 10);
// вывод среднего арифметического cout< < " Srednee= " < < Average(ar, 10);
return 0; }
void Input(int* a, int N) { cout< < " Input the numbers: " < < endl; for (int i=0; i< N; i++) { cout< < " a[" < < i< < " ]= "; cin> > a[i]; cout< < endl; } } float Average(int* a, int N) { int sum=0;
// вычисления суммы элементов for (int i=0; i< N; i++) sum+=a[i]; // возвращение среднего арифметического элементов массива return (float)sum/N; } 3б работа с динамическим массивом.
#include " stdafx.h" #include < iostream>
using namespace std;
// объвление функций // функция для ввода чисел массива void Input(int* a, int N); // функция для вычисления среднего арифметического для заданного массива float Average(int* a, int N);
int _tmain(int argc, _TCHAR* argv[]) { int* arptr; // указатель на int - используется как указатель на первый // элемент массива
int n; // количество элементов массива
cout< < " Input the quantity of elements: ";
// ввод количества элементов массива cin> > n;
// выделение памяти под n элементов массива целых чисел arptr = new int [n];
// ввод массива Input (arptr, n);
// вывод среднего арифметического cout< < " Srednee= " < < Average(arptr, n);
// освобождение памяти от массива delete [] arptr;
return 0; }
void Input(int* a, int N) { cout< < " Input the numbers: " < < endl; for (int i=0; i< N; i++) { cout< < " a[" < < i< < " ]= "; cin> > a[i]; cout< < endl; } } float Average(int* a, int N) { int sum=0;
// вычисления суммы элементов for (int i=0; i< N; i++) sum+=a[i]; // возвращение среднего арифметического элементов массива return (float)sum/N; } Многомерные массивы
Статические массивы В языке C можно использовать многомерные массивы. Размерность массива определяется количеством индексов, используемых для указания конкретного элемента. Также как и одномерные массивы, элементы многомерных массивов в памяти размещаются последовательно. При этом быстрее всего меняется последний индекс. Так для массива int mas[3][2]; в памяти формируется такая последовательностьразмещения:
[0][0], [0][1], [1][0], [1][1], [2][0], [2][1]
Инициализация многомерных массивов может быть выполнена двумя способами: (1) как одномерного массива, при этом значения надо задавать согласно размещению элементов массива в памяти:
int mas[3][2]={0, 1, 2, 3, 4, 5};
(2) как многомерного массива, приєтом каждое измерение представляется как массив:
int mas[3][2]={ {0, 1}, {2, 3}, {4, 5} };
Доступ к элементам многомерного массива производится указанием индексного выражения:
mas[2][1] при этом для обращения к элементу массива индексное выражение приводится к выражению с указателями:
*(*(mas+2)+1) что следует из pe[ie] ó *(pe+ie).
Отсюда также следует, что mas является переменной указателем типа: int **mas;
что означает, что переменая mas является указателем на указатель типа int*.
|
Последнее изменение этой страницы: 2017-03-14; Просмотров: 321; Нарушение авторского права страницы