Автор: Пользователь скрыл имя, 17 Января 2011 в 18:57, курс лекций
6 тем.
void f ( int * a ) //определение функции
{
(* a )++;
}
int main ()
{
int x =10;
f (& x ); //вызов функции
return 0;
}
При передаче параметра по ссылке в объявлении функции перед именем параметра указывается операция взятия адреса &. В этом случае в теле функции и при вызове функции операция разадресация выполняется неявным образом, т.е. без участия программиста. Например :
void f ( int & a ) //определение функции
{
a ++;
}
int main ()
{
int x =10;
f ( x ); //вызов функции
return 0;
}
Рассмотрим на примере разницу в передаче параметров.
#include <iostream>
using namespace std;
void f(int a, int *b, int &c) // определение функции f
{
a+=10;
(*b)+=10;
c+=10;
cout <<"f:\t"<<a <<"\t" << *b <<"\t" <<c <<endl;
}
int main()
{
int x=10, y=20, z=30;
cout <<"main:\t"<<x <<"\t" <<y <<"\t" <<z <<endl;
f( x , & y , z ); //вызов функции f
cout <<"main:\t"<<x <<"\t" <<y <<"\t" <<z <<endl;
return 0;
}
Результат работы программы:
main : 10 20 30
f : 20 30 40
main: 10 30 40
В данном примере:
1) параметр а передается по значению, поэтому фактический параметр х не изменил свое значение после завершения работы функции f;
2) параметр b передается по указателю, а с - по ссылке, поэтому фактические параметры y и z изменили свое значение после завершения работы функции f.
2.4. Классы памяти
Рассмотрим основные
правила использования
· Необязательный спецификатор класса
памяти может принимать одно из значений auto , extern , stati
· Место описание переменной и спецификатор класса памяти определяют область действия, время жизни и область видимости переменной.
Область действия — это часть программы, в которой переменную можно использовать для доступа к связанной с ней области памяти. В зависимости от области действия переменная может быть локальной или глобальной. Если переменная описана внутри блока (блок соответствует содержимому парных фигурных скобок), она называется локальной, область ее действия — от точки описания до конца текущего блока, включая все вложенные блоки. Если переменная описана вне любого блока,она называется глобальной, и областью ее действия считается файл, в котором она определена, от точки описания до его конца.
Класс памяти определяет время жизни и область видимости программного объекта (в частности, переменной). Если класс памяти не указан явным образом, он определяется компилятором исходя из контекста объявления.
Время жизни может быть постоянным (в течение выполнения программы) и временным (в течение выполнения блока).
Областью
видимости идентификатора назыв
Для задания класса памяти используются следующие спецификаторы:
auto — автоматическая переменн
extern —означает, что
переменная определяется в другом месте
программы (в другом файле или дальше по
тексту). Используется для создания переменных,
доступных во всех модулях программы,
в которых они объявлены. Если переменная
в том же операторе инициализируется,
то спецификатор extern игнорирует
static —статическая переменная
register — аналогично auto , но память выделяется по возможности в регистрах процессора. Если такой возможности у компилятора нет, переменные обрабатываются как auto .
Пример описания переменных:
int a; // 1
глобальная переменная
а
int main()
{
int b; // 2
локальная переменная b
extern int х; //3 переменная
хопределена в другом
месте
static с; //4 локальная
статическая переменная
с
а =1; //5 присваивание
глобальной переменной
int а; //6 локальная переменная
а
а = 2; // 7 присваивание
локальной переменной
::а = 3; //8 присваивание
глобальной переменной
return 0;
}
int х = 4; //9 определение и инициализация х
В этом примере глобальная переменная а определена вне всех блоков. Память под нее выделяется в сегменте данных в начале работы программы,областью действия является вся программа. Область видимости — вся программа,кроме строк 6-7, так как в первой из них определяется локальная переменная стем же именем, область действия которой начинается с точки ее описания и заканчивается при выходе из блока. В строке 8 происходит обращение к глобальной переменной а через операцию доступа к области видимости ::.
Переменные b и с — локальные, область их видимости — блок, но время жизни различно: память под b выделяется в стеке при входе в блок и освобождается при выходе из него, а переменная с располагается в сегменте данных и существует все время, пока работает программа.
Если при определении начальное значение переменных явным образом не задается, компилятор присваивает глобальным и статическим переменным случайное значение соответствующего типа. Автоматические переменные не инициализируются. Имя переменной должно быть уникальным в своей области действия (например, в одном блоке не может быть двух переменных с одинаковыми именами).
Следует отметить, что вся память, используемая программой, распределяется между сегментом данных, стеком и кучей. Дополнительно память выделяется под код самой программы.
В сегменте данных хранятся
внешние (глобальные) и статические идентификаторы
(имеющих спецификаторы extren и static)
Стек используется для хранения локальных (auto– автоматических) идентификаторов. Память под данные идентификаторы выделяется стеке при их описании и освобождается при завершении работы блока, в котором они описаны.
Куча используется для хранения данных, работа с которыми реализуется через указатели и ссылки. Сами указатели хранятся либо в сегменте данных, либо в стеке (в зависимости от указанного спецификатора класса памяти), а память для размещения данных динамически выделяется или освобождается в куче программистом с помощью специальных средств языка С++ (см. раздел 6.1).
2.5. Примеры использования функций при решении задач
1. Дана функция
f(x)=x3- x 2 + x -1. Найти значение
выражения z=f(2a)+f(b+c), где a, b,c – вещественные
числа.
Текст
программы
#include <iostream>
#include <cmath>
using namespace std;
float f(float x) // функция вычисляет f(x)
{
return pow(x,3)-pow(x,2)+x-1;
}
int main()
{
float a,b,c, z;
cout <<"Ведите значение а, b , c ="; cin >> a >> b >> c ;
z=f(2*a)+f(b+c); cout <<"z=" <<z <<endl;
return 0;
}
Результат работы программы:
a b c z
1 2 3 109
2. Дана сторона
квадрата. С помощью одной функции
вычислить его периметр и
Текст программы
#include <iostream>
#include <cmath>
using namespace std;
void func(float x, float &p, float &s)
{
p=4*x;
s=x*x;
}
int main()
{
float a, p, s;
cout <<" а =";
cin >>a;
func(a, p, s);
(p>s)? cout << " периметр ": cout <<" площадь ";
return 0;
}
Результат работы программы:
а ответ
1 периметр
5 площадь
ОПЕРАТОРЫ С++
3.1. Операторы следования
рограмма на языке С++ состоит из последовательности операторов, каждый из которых определяет законченное описание некоторого действия и заканчивается точкой с запятой. Все операторы можно разделить на 4 группы: операторы следования, операторы ветвления, операторы цикла и операторы передачи управления.
Операторы следования выполняются компилятором в естественном порядке: начиная с первого до последнего. К операторам следования относятся:оператор выражение и составной оператор.
Любое выражение,
завершающееся точкой с запятой, рассматривается
как оператор, выполнение которого заключается
в вычислении значения выражения или выполнении
законченного действия. Например:
++i; | //оператор инкремента |
x += y ; | //оператор сложение с присваиванием |
f ( a , b ); | // вызов функции |
x = max ( a , b )+ a * b ; | //вычисление сложного выражения |
Частным случаем оператора выражения является пустой оператор ;Он используется, когда по синтаксису оператор требуется, а по смыслу — нет. В этом случае лишний символ ; является пустым оператором и вполне допустим, хотя и не всегда безопасен. Например, случайный символ ; после условия оператора while или if может совершенно поменять работу этого оператора.
Составной оператор или блок представляет собой последовательность операторов, заключенных в фигурные скобки. Блок обладает собственной областью видимости: объявленные внутри блока имена доступны только внутри данногоблока или блоков, вложенных в него. Составные операторы применяются в случае,когда правила языка предусматривают наличие только одного оператора, а логика программы требует нескольких операторов. Например, тело цикла while должно состоять только из одного оператора. Если заключить несколько операторов в фигурные скобки, то получится блок, который будет рассматривать компилятором как единый оператор.
3.2. Операторы ветвления
Операторы ветвления позволяют изменить порядок выполнения операторов в программе. К операторам ветвления относятся условный оператор if и оператор выбора switch.