Использование ссылок для передачи параметров функции — КиберПедия 

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...

Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...

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

2022-10-27 74
Использование ссылок для передачи параметров функции 0.00 из 5.00 0 оценок
Заказать работу

Перепишем приведенную выше программу, но вместо указателей используем ссылки.

void swap (int&,int&);

int main (){

int x=1, y=2;

cout<< " x=" <<x<< " y=" <<y;// x=1 y=2

swap (x,y);

cout<< " x=" <<x<< " y=" <<y; // x=2 y=1

}

void swap (int&a,int&b){

int c;

c=a;

a=b;

b=c;

}

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

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

double x=1.0;

int f1(){

int y=1;

cout<<y; //1

}

intmain (){

double x=2.0;

cout<<x<<" "<<::x; // 2.0 1.0

floaty=2;

cout << y; //2

}

Пример. Найти наибольшее из трех чисел.

int z;

void MAX(int x; int y){

if (x>y) z=x;

else z=y;

}

int main (){

inta,b,c;

a= 1; b=2; c=3;

MAX (a,b);

MAX (c,z);

cout << z;

}

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

#include <iostream>

using namespace std;

int * p 1, * p 2; // Глобальные указательные на тип int переменные

voidallocate () {

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

p 1 = newint; // Выделитьпамять

* p 1 = 88;    // Присвоитьзначениепоуказателю p 1

p 2 = newint (99); // Выделить память и присвоить значение

}

int main() {

allocate();

cout << *p1 << endl; // 88

cout << *p2 << endl; // 99

// освобождениепамяти

delete p1;

deletep 2;

return 0;

}

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

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

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

#include <iostream>

#include"myfuncs.h"

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

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

В С++ определены следующие библиотеки и соответствующие заголовочные файлы:

- <ios>, <iostream>, <istream>, <ostream>, <fstream>, <sstream>

- <iomanip>

- <string>

- <regex>

- <random>

- <limits>

- <stdexcept>, <exception>

- <complex>, <tuple>, <valarray>

- <locale>

- <typeinfo>

- <chrono>

- <codecvt>, <new>, <ratio>, <system_error>, <type_traits>.

Стандартная библиотека C ++ не поддерживает работу с датами. С++ наследует структуры и функции для работы с датой и временим с языка С. Чтобы получить доступ к данным функциям и структурам, необходимо подключить заголовочный файл <ctime>.

Существует четыре структурных типа данных, предназначенных для работы со временем: clock _ t, time _ t, size _ t, и tm. Типы clock _ t, size _ t и time _ t имеют возможность представлять системное время, а data это целочисленный тип.

Тип tm содержит дату и время в форме С-структуры со следующим набором элементов:

struct tm {

inttm_sec; // секунды 0 до 61

inttm _ min; // минуты 0 до 59

int tm_hour; // часы 0 до 24

inttm _ mday; // дни месяца 1 до 31

inttm _ mon; // месяцы 0 до 11

int tm_year; // year since 1900

inttm _ wday; // дни недели, начиная с воскресения

inttm _ yday; // номер дня, начиная с 1 января

inttm _ isdst; // часы с учетом «летнего времени»

}

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

 

Таблица 1.2 – Функции для работы с датой и временем

 

Функция Назначение
time_t time(time_t *time); Возвращает количество секунд между текущей календарной датой системы и 01.01.1970 г. Если системного времени нет, то возвращает 1.
char *ctime(const time_t *time); Возвращает указатель на строку следующего формата: daymonthyearhours: minutes: secondsyear \ n \0.
struct tm *localtime(const time_t *time); Возвращает указатель на структуру tm, в которой представлено текущее время.
clock_t clock(void); Возвращает количество времени, прошедшего с запуска программы. Если время не определено, то возвращает 1.
char * asctime (const struct tm * time); Возвращает указатель на строку, которая содержит информацию, хранящуюся в структуре * time, время ковертировано в форму: daymonthdatehours:minutes:secondsyear\n\0
struct tm *gmtime(const time_t *time); Возвращает указатель на время в форме tm-структуры. ВремяпредставленовCoordinated Universal Time (UTC).
time_t mktime(struct tm *time); Возвращает указатель на метку времени, полученную на основании данных tm-структуры.
double difftime (time_t time2, time_t time1); Вычисляет разницу между time1 иtime2 в секундах.
size_t strftime(); Используется, чтобы отформатировать дату и время в специальный формат.

В следующем примере продемонстрирован вывод на экран текущей даты и времени, а также CoordinatedUniversalTime.

#include <iostream>

#include <ctime>

using namespace std;

intmain (){

// текущие дата и время, полученные на основе системного времени

time _ tnow = time (0);

// текущая метка времени конвертируется в строку

char* dt = ctime(&now);

cout << "The local date and time is: " << dt << endl;

// текущая метка времени конвертируется tm -структуру для UTC

tm *gmtm = gmtime(&now);

dt = asctime(gmtm);

cout << "The UTC date and time is:"<< dt << endl;

}

В результате на экран будет выведено:

The local date and time is: Sat Jan 8 20:07:41 2011

 

The UTC date and time is:Sun Jan 9 03:07:41 2011

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

#include <iostream>

#include <ctime>

using namespace std;

intmain (){

// // текущие дата и время, полученные на основе системного времени

time_t now = time(0);

cout << "Number of sec since January 1,1970:" << now << endl;

tm * ltm = localtime (& now);

// вывод на экран различных компонент tm -структуры.

cout << "Year" << 1900 + ltm->tm_year<<endl;

cout << "Month: "<< 1 + ltm->tm_mon<< endl;

cout << "Day: "<< ltm->tm_mday << endl;

cout << "Time: "<< 1 + ltm->tm_hour << ":";

cout << 1 + ltm->tm_min << ":";

cout << 1 + ltm->tm_sec << endl;

}

В результате на экран будет выведено:

Number of sec since January 1, 1970:1294548238

Year: 2011

Month: 1

Day: 8

Time: 22: 44:59

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

longFact (intn){

if (n<0) return 0;

if (n==0) return 1;

returnn*Fact (n-1);

}

Известный факт 0!=1 в нашем случае это будет опорное значение от которого начинается раскручивание всех последующих значений факториала. Последовательность рекурсивных обращений функции должна обязательно выходить на определенное значение. Весь маршрут последовательных вхождений компьютер запоминает в специальной области памяти называемой СТЭКОМ.

Таким образом, выполнение рекурсивных функций происходит в 2 этапа, прямой ход – заполнения стека, и обратный ход – цепочка вычислений по обратному маршруту сохраненному, в стеке. Обратить внимание, что размер стека ограничен.

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

voidfunc 1(int * x, intn) { /* указатель */

/*  */

}

или как

void fun c 1(int x [10]){ /* массив определенного размера */

/*  */

}

или

void funс1(int х[]){ /* массив без определенного размера */

/* */

}

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

intx [10];

func 1(x);

Следует помнить, что внитри функции работа происходит с оригиналом массива, а не с его копией.

Пример.Найти Евклидову норму строк матрицы.

double Norma (double *X; int n);{

int i;

double S=0;

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

S+=X[i]*X[i];

returnsqrt(S);

}

intmain(){

doubleA[5][10];

for (i=0;i<5;i++)

cout << Norma (A [ i ], 10);//передаем в функцию строку мартицы

}

//Упражнение определить функцию вывода двумерного массива

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

return-type (* function-ptr-name) (parameter-list)Примеры объявлений: double (* fp)(int, int) // fp указатель на функцию, которая принимает два параметра типа int и возвращает тип double double *dp;        // dp указательнатип double (double-pointer) double * fun (int, int) // fun функция, которая принимает два параметра типа int и возвращает указатель на тип double doublef (int, int); // f функция, которая принимает два параметра типа int и возвращает тип double fp = f;            // присваивается указателю fp адрес функции fВ следующем программном коде продемонстрирован вызов функции через указатель и по имени: int number1 = 5, number2 = 6; int (*fp)(int,int)=&add;    // вызовфункциичерезуказатель cout << fp(number1,number2) << endl; // вызовфункциипоимени cout << add(number1,number2) << endl; В следующем примере в зависимости от введенного знака операции выполняется то или иное действие над двумя переменными типа int: #include <iostream.h> int add(int n1, int n2) { return n1 + n2; } int sub(int n1, int n2) { return n1 - n2; } int mult(int n1, int n2) { return n1 * n2; } int main() { int number1 = 5, number2 = 6; int (*fp)(int,int); char c;// знакоперации cout <<"Введите знак операции"; cin >> c; switch(c){ case '+': fp=&add; break; case '-': fp=&sub; break; case '*': fp=&mult; break; default: cout <<"Такая операция не реализована."; return 0; }; cout << number1<<c<<number2<<"="<<fp(number1,number2) << endl; } Указатель на функцию можно передавать как параметр в другую функцию. Пример: #include <iostream> using namespace std; int arithmetic(int, int, int (*)(int, int)); /*функцияпринимаеттриаргумента, 2 типа int и указатель на функцию, которая принимает два целочисленных аргумента и возвращает значение типа int */ int add(int, int); int sub(int, int); int add(int n1, int n2) { return n1 + n2; } int sub(int n1, int n2) { return n1 - n2; } int arithmetic(int n1, int n2, int (*operation) (int, int)) { return (*operation)(n1, n2); } int main() { int number1 = 5, number2 = 6; // выполняетсясложение number1 и number2 cout << arithmetic(number1, number2, add) << endl; // выполняетсявычитание number1 и number2 cout << arithmetic(number1, number2, sub) << endl; }

Встраиваемые (Inline) функции. В С++ можно задать функцию, которая на самом деле не вызывается, а ее тело встраивается в программу на этапе компиляции в месте ее вызова (подобно макроопределениям с параметрами в языке С). Inline-функции могут выполняться гораздо быстрее, чем обычные функции, т.к. выполнение машинных команд, которые генерируют вызов функции, передачу параметров, возврат значения, занимает определенное время. Если же встраниваеме функции состоят из большого объема кода, то это приведет к существенному увеличению объема программы вцелом. Из-за этого применение встраиваетмых функций ограничивается короткими функциями. Чтобы функция было объявлена как встраиваемой, перед ее объявлением необходимо написать ключевое слово inline.

Пример.

inline isEven(int x) {return!(x%2);}

int main(){

int n=10;

cout<< " Число "<<n;

if(isEven(n)) cout<< " четное.";

else cout << "нечетное.";

}

На экран будет выведено:

Число 10 четное.

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

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

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

   тип main(){/*…*/}

                           или

   тип main(intargc, char*argv[]){/*…*/}

Функция main() может иметь два параметра. Имена параметров в программе могут быть любыми, но принято использовать argc и argv.

- a rgc определяет количество параметров, передаваемых функции, включая имя самой программы.

- a rgv является указателем на массив указателей типа char. Каждый элемент массива содержит указатель на отдельный параметр командной строки, хранящееся в виде С-строки, оканчивающейся null-символом.

Первый элемент массива argv[0] ссылается на полное имя, запускаемого на выполнение файла.

Следующий argv[1] указывает на первый параметр; argv[2] – на второй и т.д. Параметр argv[argc] должен быть равен 0. Если функция main() ничего не возвращает, вызвавшая система получит значение,означающее успешное завершение. Ненулевое значение означает аварийное завершение. Оператор возврата из main() можно опускать.

Использование в программном кодепараметоров функции main (). В качестве примера напишем программу сложения двух чисел, которую назовем, например, sumToArg. Программный код сохраняем в файле sumToArg. cpp, следовательно, исполнимый код программы будет находиться в файле sumToArg. exe.

/*Программа выполняет сложение двух чисел, введенных из командной строки*/

#include<stdlib.h>

#include<stdio.h>

int main(intargc, char*argv[]){

   floata,b;//слагаемые

   /*Массив argv[] содержит значения параметров в виде строк. argv [0]- название программы; argv [1] – первое слагаемое; argv [2] – второе слагаемое.*/Ч

   //Для выполнения сложения их надо перевести в тип float

               a=atof(argv[1]);

               b=atof(argv[2]);

               cout<<a<<"+"<<b<<"="<<a+b);

   return 0;

}

   Как сказано выше параметры,в функцию приходят как строки. Но для выполнения арифметических действий значения параметров нужно перевести к нужному нам типу данных. Для этого имеется ряд функций в библиотеке stdlib. h.

atof (argv [1]) – переводит аргумент к типу float;

atoi (argv [1]) – переводит аргумент к типу int.

Запуск программ из командной строки. Для того чтобы запустить программу воспользуемся командной строкой cmd.С помощью команды cd пе реходим в директорию, где находится программа sumToArg. exe. Далее пишем название программы, параметры (разделяются пробелами) и нажимаем клавишу Enter, чтобы запустить программу.

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

 

#include<stdlib.h>

#include<stdio.h>

int main(intargc, char*argv[]){

int count=0;

for(i=1;i<argc;i++)

if(atof(argv[i])<0) count++;

if(count==0)cout<<"No";

else cout<<"otric - "<<count; return 0;

}

Количество членов последовательности можем вычислить исходя из значения параметра argc. Сами значения последовательности располагаются в массиве argv [] начиная с индекса 1. Элемент argv [0] содержитимяпрограммы.

 

Контрольные вопросы и задания

1. Раскройте суть понятия функция.

2. Приведите синтаксис объявления, определения и вызова функции.

3. Какие виды передачи параметров в функцию имеются в С++?

4. Изобразите в виде блок-схемы алгоритм выполнения функции

5. Объясните назначения прототипа функции.

6. Какие библиотеки функций имеются в языке С++? Как их подключить к разрабатываемому программному коду?

7. В чем особенность встроенных функций?

8. Какие параметры имеет функция main()? Приведите пример их использования в программе. 

 

Классы и объекты


Поделиться с друзьями:

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

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

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

Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.102 с.