Смекни!
smekni.com

Язык прораммирования С++ (стр. 2 из 7)

exp(V1) – вычисления показательной функции с основанием e,

asin(V1), atan(V1) – вычисления арксинуса и арктангенса.

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

Функция может иметь несколько параметров. Например, функция atan2(y,x), которой передается два вещественных аргумента, вычисляет арктангенс угла, лежащего в прямоугольном треугольнике с катетами x,y против стороны y, причем второй аргумент x может быть равным нулю (при этом арктангенс будет равен π/2).

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

#include<math.h>.

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

R1=floor(V1); или с избытком r=ceil(S);.

Для округления до ближайшего целого нет стандартной функции, но можно выполнить оператор

R1=floor(V1+0.5);

Как и в Паскале, можно узнать, сколько байтов требуется для хранения переменной, применив к ней операцию sizeof(). Объявим переменные

intA,B;

floatC;

Операторы

A=sizeof(int);

A=sizeof(B);

дадут одинаковый результат – размер переменной типа int.

Оператор A=sizeof(C); запишет в A число 4 – размер переменно типа float.

4. Реализация функций в тексте программы

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

Любая функция, как и главная функция main() состоит из заголовка и заключенного в фигурные скобки тела функции. Пусть, например, нам необходима функция area (l,w) вычисления площади прямоугольного участка по его длине l и ширине w. Эта функция может быть реализована следующим образом

float area(int x, int y)

{float s;

s= x*y;

return s;

}

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

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

float area(int x, int y)

{returnx*y;

}

В функции main мы использовали обозначение void и вместо возвращаемого значения и вместо списка параметров – это тоже тип данных, не знаю, как его лучше называть, то ли пустой, то ли неопределенный это пустые, не имеющие значения данные. Неизвестно даже, сколько байтов нужно для их хранения – поэтому и объявить переменную типа void нельзя. Этот тип указывают как раз там, где обычно ожидают какого-нибудь значения, а его нет. То есть, заголовок voidmain(void), указывает, что функция main не получает параметров и не возвращает значения. (На Паскале такая конструкция называлась бы процедурой без параметров). Поместим вызов нашей функции в главную программу:

void main(void)

{float A,B;

int b,R;

b = 4;

A = area(5,b);

B = area(20,30);

}

При выполнении программы сначала оператором b=4; в переменную b занесется число четыре. Следующий оператор вызовет вычисление функции area(5,b); для того, чтобы записать ее значение 25 в переменную A.

Выполнение операции вызова функции area(5,b) заключается в следующем:

– программа перестает выполнять операторы главной функции main()и переходит к выполнению функции area(), при этом ей передаются указанные при вызове значения параметров – в параметр x запишется число 5, а в параметр y значение переменной b – число четыре;

– выполняется первый оператор, записанный в теле функцииarea(), то есть строкаs= x*y;. При этом функция вычислит произведение 5*4 и запишет его в переменную s.

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

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

Как видим, из описания самой функции нельзя увидеть, чему равны параметры x и y. Они потому и называются формальными, что получают фактические значения только во время выполнения программы – в момент вызова функции. Так, при следующем вызове B=area(20,30); формальные параметры x и y получат значения 20 и 10. Как мы помним из предыдущих глав, процедуры и функции тем и хороши, что позволяют проделывать одни и те же действия, но с разными исходными данными.

Замечание. Когда компилятор переводит строки языка С++ в машинные коды, он, как и мы, просматривает программу сверху вниз. Поэтому, к моменту вызова функции area() он уже обработал описание функции и знает, что функция должна получать в качестве параметров два целых числа и возвращать вещественный результат. Поэтому если вставить в программу операторы

R=area(20,30,70);

B=area(2.5,10);

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

Если мы запишем функцию area() после главной, то во время обработки оператора A=area(5,b); у компилятора еще не будет информации для проверки правильности вызова.

Так что же, мы не можем поместить функцию вычисления площади после главной функции? Можем, но заголовок функции area()придется написать еще раз, как показано ниже:

float area(int x, int y);

void main(void) {

float A,B;

int b,R

b=4; A=area(5,b); B=area(20,30);

}

float area(int x, int y){

float s;

s= x*y;

return s;

}

В первой строке программы записан заголовок floatarea(intx, inty);. Точка с запятой в конце заголовка говорит о том, что ниже не будет тела функции. Это только предописание, или прототип функции, позволяющий проверить правильность ее вызова. Сама функция описана после главной программы.

Прототипы написанных в программе нестандартных функций тоже можно поместить в заголовочный файл, например, myproto.h. Он обычно имеет расширение h и называется (от слова header) заголовочным файлом. В исходный текст программы помещают строку #include “myproto.h”.

Напомним, что перед компиляцией программы ее исходный текст подвергается предварительной обработке – прекомпиляции. Прекомпилятор (он же препроцессор) просматривает текст файла, находит строчки, которые начинаются со слова #include (чтобы их легче находить, в строке перед этим словом нельзя писать ничего, кроме пробелов) и заменяет строчку текстом из указанного в ней заголовочного файла. Файл stdio.h препроцессор должен искать в подкаталоге include среды разработки, а файл myproto.h обычно находится в текущем каталоге – там же, где исходный текст программы. Чтобы указать, где следует искать заголовочный файл, имя stdio.h пишется в угловых скобках, а имя myproto.h в кавычках.

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

#defineABC 32.5

Препроцессор просмотрит весь следующий за ней текст и везде, где встретится имя ABC заменит его на 32.5.

Рассмотрим в качестве примера следующую задачу:

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

Для решения задачи создадим заголовочный файл round.h следующего содержания:

#define Pi 3.141592653

float Round(int);

Тогда текст программы будет иметь следующий вид:

#include <stdio.h>

#include “round.h”

int r;

float S;

void main(void)

{

printf("Введитерадиус ");

scanf("%d",&r);

S=Round(r);

printf("Радиус %d &bsol;n площадь %g &bsol;n", r, S);

}

float Round(int p)

{ return Pi*p*p;

}

Строка #include “round.h” включит в текст этой программы прототип функции и константу Pi.

Замечания

1. В настоящее время различные фирмы предлагают разные версии компиляторов для языка C++. Для проверки приводимых примеров в среде MSDOS мы будем использовать компилятор фирмы Borland а для среды Windows – Visual С++ фирмы Microsoft. Создатели языков высокого уровня стремятся к тому, чтобы написанная на данном языке программа одинаково выполнялась под управлением разных операционных систем и на компьютерах с различной архитектурой. Но идеально переносимого (мобильного) текста программ обычно не получается. Например, при использовании компилятора BorlandC++ объявлять константу Pi нет необходимости. В файле math.h значения ,/2,1/ и прочие определены следующим образом:

#define M_PI 3.14159265358979323846

#define M_PI_2 1.57079632679489661923

#define M_PI_4 0.785398163397448309616

#define M_1_PI 0.318309886183790671538

#define M_2_PI 0.636619772367581343076

#define M_1_SQRTPI 0.564189583547756286948

#defineM_2_SQRTPI1.12837916709551257390.

Правда, имена выбраны таким образом, что не каждый найдет эти константы. Но в файле math.h, который использует VisualC++, таких констант нет. В разных версиях могут отличаться не только содержимое, но и состав заголовочных файлов. Например, файл mem.hесть в BorlandC++, и отсутствует в VisualC++. Но прототипы функций, описанные в mem.h, можно найти в файле memory.h среды VisualC++.