Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Значения после функции 1001 и 1001



Как видите, значения, которые функция change_valuesприсваивает параметрам, остаются и после завершения функции. Чтобы понять, почему изменения, которые функция выполнила над переменными, остались после ее завершения, необходимо вспомнить, что функция имеет доступ к ячейке памяти каждой переменной. Если вы передаете параметры по адресу, C++ помещает адрес каждой переменной в стек, как показано на рис. 10.2.

Рис. 10.2. Передача параметров по адресу.

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

Изменение значений параметров в функциях

Для изменения значения параметра в функции, функция должна знать адрес параметра в памяти. Следовательно, ваша программа должна передать адрес параметра с помощью оператора адреса C++:

some_function(& some_variable);

Внутри функции вы должны сообщить C++, что функция будет работать с адресом памяти (указателем). Для этого при объявлении вы предваряете имя параметра звездочкой:

void some_function(int *some_variable);

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

*some_variable = 1001;
cout < < *some_variable;

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

 

Второй пример

Если ваша программа передает указатели на параметры, параметры могут быгь любого типа, например int, float или char. Функция, которая использует указатели, объявляет переменные соответствующего типа, предваряя имя каждой переменной звездочкой, подтверждающей, что такая переменная является указателем. Следующая программа SWAPVALS.CPP передает адреса двух параметров типа floatв функциюswap_values.Функция в свою очередь использует указатели на каждый параметр, чтобы обменять значения параметров:

#include < iostream.h>

void swap_values(float *a, float *b)

{
float temp;
temp = *a;
*a = *b;
*b = temp;
}

void main(void)

{
float big = 10000.0;
float small = 0.00001;
swap_values(& big, & small);
cout < < «Big содержит » < < big < < endl;
cout < < «Small содержит » < < small < < endl;
}

Как видите, программа передает параметры в функцию swap_valuesпо адресу. Внутри функции программа использует указатели на ячейки памяти параметров. Давайте более внимательно посмотрим на действия внутри функции swap_va lues.Как видите, функция объявляет аи bкак указатели на значения типа float:

 

void swap_values(float *a, float *b)

Однако функция объявляет переменную tempпросто как float, ане как указатель на float.float temp;

Рассмотрим следующий оператор:

temp = *а;

Этот оператор побуждает C++ присвоить переменной tempзначение указываемое переменной а(т. е. значение переменной big, равное 10000.0). Поскольку tempимеет тип float, присваивание корректно. Переменная-указатель представляет собой переменную, которая хранит адрес. Следующий оператор объявляет tempкак указатель на ячейку памяти, содержащую значение типа float.

float *temp;

В данном случае tempможет хранить адрес значения с плавающей точкой но не само значение.

Если вы удалите оператор разыменования (*), стоящий перед переменнойавнутри присваивания, то оператор будет пытаться присвоить значение, хранимое в а(которое является адресом), переменной temp.Посколькуtempможет содержать значение с плавающей точкой, но не адрес значения с плавающей точкой, возникнет ошибка.

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

Использование ассемблерных листингов для лучшего понимания работы компилятора

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

 

ЧТО ВАМ НЕОБХОДИМО ЗНАТЬ

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

Из урока 11 вы выясните, как функции библиотеки этапа выполнения, обеспечиваемые компилятором C++, могут ускорить программирование, позволяя быстро разрабатывать сложные программы. Однако до изучения урока 11 убедитесь, что вы освоили следующие основные Концепции:

 

1.

1. Пока вы не используете указатели или ссылки C++, функция не может изменить значение параметра.

2. Когда ваша программа передает параметр в функцию, C++ помещает копию значения параметра во временный участок памяти, называемый стеком. Любые изменения, которые функция осуществляет над параметром, влияют только на эту копию, расположенную в стеке.

3. Для изменения значения параметра функция должна знать адрес соответствующей переменной.

4. Используя оператор адреса C++ (& ), ваши программы могут передать адрес переменной в функцию.

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

6. Если функции требуется использовать значение, на которое ссылаются (указывают) по указателю, функция должна предварять имя переменной-указателя звездочкой, т. е. оператором разыменования C++.

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

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

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

• Некоторые компиляторы обращаются к библиотеке этапа выполнения как к интерфейсу прикладных программ или API.

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

ИСПОЛЬЗОВАНИЕ ФУНКЦИЙ БИБЛИОТЕКИ ЭТАПА ВЫПОЛНЕНИЯ

Из урока 9 вы узнали, что до того, как ваши программы смогут вызвать функцию, компилятор C++ должен узнать определение или прототип функции. Поскольку функции библиотеки этапа выполнения не определены в вашей программе, вы должны указать прототип для каждой библиотечной функции, которую намерены использовать. Для упрощения использования библиотечных функций компилятор C++ предоставляет заголовочные файлы, содержащие корректные прототипы. Таким образом, вашим программам необходимо просто включить требуемый заголовочный файл с помощью оператора # include, а затем вызвать необходимую функцию. Например, следующая программа SHOWTIME.CPP будет использовать функции библиотеки этапа выполнения t ime и ctime для вывода текущей системной даты и времени. Прототипы этих двух функций библиотеки этапа выполнения содержатся в заголовочном файле time.h:

#include < iostream.h>
#include < time.h> // Для функций библиотеки этапа выполнения

void main(void)

{
time_t system_time;
system_time = time(NULL);
cout < < «Текущее системное время » < < ctime(& system_time) < < endl;
}

Когда вы откомпилируете и запустите эту программу, на вашем экране появятся текущие системные дата и время:

С: \> SHOWTIME < ENTER>


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-05-30; Просмотров: 641; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.013 с.)
Главная | Случайная страница | Обратная связь