Программирование >>  Процедурные приложения 

1 ... 40 41 42 [ 43 ] 44 45 46 ... 150


Дополнительные особенности функций

Макроподстановка функций

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

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

inline. срр

Эта программа на языке C++ содержит пример макроподстановки функции.

#include <iostream.h>

inline long squareit(int iValue) (return iValue * iValue;} int main ()

int iValue;

for(iValue = 1; ivalue <= 10; iValue++)

cout<< Квадрат числа << iValue<< равен

<< squareit(iValue) << \n ;. return(0); }

Функция squareit(), возвращающая квадрат целочисленного аргумента ivalue, описана со спецификатором inline. Когда в программе будет обнаружен вызов данной функции, компилятор подставит в этом месте строку ivalue*ivalue. Другими словами, компилятор заменяет вызов функции ее телом, присваивая при этом аргументам функции их фактические значения.

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

Перегрузка функций

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

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

overload.cpp

Эта программа на языке C++ содержит пример перегрузки функции.

#include <iostream.h> int adder (int iarray[]); float adder (float f array []); int main() {



int iarray[7] = {5,1, 6, 20,15,0, 12);

float farray[7] = {3.3,5.2,0.05,1.49,3.12345,31.0,2.007};

int isum; float fsum;

isura = adder (iarray) ;

fsum= adder (f array) ;

cout<< Сумма массива целых чисел равна << isura << \n ; cout<< Сумма массива дробных чисел равна << fsum<< \n ; return ( 0 ).;

int adder(int iarrayt]) { int i;

int ipartial;

ipartial = iarray[0]; for(i= 1; i < 7; i++) ipartial += iarray[i]; return(ipartial);

float adder (float farrayf]) { int i;

float f partial, fpartial = f array [0]; for(i= 1; i < 7; i++) fpartial += farray[i]; return (fpartial) ; }

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

int имя функции(int имя аргумента) ;

int имя функции(int имя аргумента) ; недопустимая перегрузка имени

Это неправильно, поскольку аргументы имеют одинаковый тип. Функции с переменным числом аргументов

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

void имя функции(int first, float second, . . . ) ;

Данный прототип говорит компилятору о том, что за аргументами firstи secondмогут следовать и другие аргументы, если возникнет такая необходимость. При этом тип последних не контролируется компилятором.

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

* ellipsis. с

* Эта программа на языке С содержит пример функции с переменным числом

* аргументов и демонстрирует использование макросов va arg, va startи va end.

#include <stdio.h> #include <stdarg.h> #include <string.h>

void vsmallest (char *szmessage, ...);



intmain() {

vsmallest( Выводим %dцелых чисел, %d %d %d ,10,4, 1);

return (0); }

void vsmallest (char *szmessage, ...)

int inumber of percent ds = 0; va listtype for ellipsis; int ipercent d format = d; char *pchar;

pchar = strchr (szmessage, ipercent d format) ; while (*++pchar != \0){ pchar++;

pchar = strchr (pchar, ipercent d format) ; inumber of percent ds++;

printf{ Выводим%d целых чисел, ,inumber pf percent ds) ; va start(type for ellipsis, szmessage); while(inumber of percent ds-)

printf( %d , va arg(type for ellipsis, int)); va end(type for ellipsis); }

Функция vsmallest() ожидает двух формальных аргументов: указателя на строку и списка неопределенной длины. Естественно, функция должна иметь возможность каким-то образом определить, сколько же аргументов она получила на самом деле. В данной программе эта информация передается в строковом аргументе.

Созданная нами функция vsmallest() частично имитирует работу стандартной функции printf (). Аргумент szmessage рассматривается как строка форматирования, в которой подсчитывается число спецификаций %d. Полученная информация позволяет вычислить количество дополнительных аргументов.

Функция strchr() возвращает адрес позиции спецификатора d в строке форматирования. Первый элемент %d игнорируется, поскольку на его месте будет выведено общее число аргументов. В первом цикле while определяется количество спецификаторов d в строке szmessage, и полученное значение заносится в переменную inumber of percent ds. По завершении цикла на экран выводится первая часть сообщения.

Макрос va start() устанавливает указатель type for ellipsis(обратите внимание на его тип - va list) в начало списка аргументов функции. Второй параметр макроса является именем обязательного аргумента анализируемой функции, который стоит непосредственно перед многоточием. Макрос va arg() возвращает очередной аргумент из списка. Второй параметр макроса указывает на тип возвращаемого аргумента (в нашей программе это тип int). Макрос va end() очищает указатель type for ellipsis, делая его равным нулю.

Область видимости переменных

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

Попытка получить доступ к переменной вне ее области видимости

В следующем примере в функции main() объявляются четыре локальные переменные. В программе как будто бы нет никаких ошибок. Тем не менее, когда функция iproduct() попытается обратиться к переменной in, она не сможет ее обнаружить. Почему? Потому что область видимости этой переменной ограничена только функцией main().

* scope. с

* Эта программа на языке С иллюстрирует проблему неправильного



1 ... 40 41 42 [ 43 ] 44 45 46 ... 150

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика