Функцияларды қолдану
Функцияны пайдаланып, цилиндрдің көлемін есептеу.
#include
/* цилиндрдің көлемін есептеу */
void main ( )
{float w(float, float); /* функция прототипі */
float a,b;
int j;
for (j=0; j<5; j++)
{printf("/nМәнді енгізіңіз a=");
scanf( "%f",&a);
printf("Мәнді енгізіңіз b=");
scanf( "%f", &b);
if ( a > 0.0 && b > 0.0 ) break;
printf("/n Қате, a>0 және b>0 болуы керекі\n");}
if (j==5)
{printf("/n мәнді өте нашар енгіздіңізі");
return;}
printf("/n Цилиндрдің көлемі =%f ", w(a,b));} /* негізгі программаның соңы */
/* цилиндрдің көлемін есептеу функциясы: */
float w(float g, float h)
{if ( g>=h )
return (3.14159*g*g*h);
else
return (3.14159*g*h*h);}
Программаның орындалу нәтижесі:
Мәнді енгізіңіз a=2.0
Мәнді енгізіңіз b=-44.3
Қате, a>0 және b>0 болуы керекі
Мәнді енгізіңіз a=2.0
Мәнді енгізіңіз b=3.0
Цилиндрдің көлемі=56.548520
Рекурсивті функциялар. Параметрлері айнымалы санды функциялар. Рекурсивтік функциялар. Си тілінде функциялар өз-өздерін шақыра алады. Функция рекурсивті деп аталады, егер функция денесіндегі операторда сол функцияның шақыруы бар болса. Рекурсивтік функцияның классикалық мысалы ретінде,
Nі =1*2*3*4*...N cанының факториалын есептеу жатады.
factorial ()
{ int a;
if (n ==1) return 1;
a= factorial (n-1)*n;
return a; }
Рекурсивтік функцияда функцияны шақыру функцияның жаңа көшірмесін құрмайды, ол жадыда жаңа локальдық айнымалылардың және параметрлердің көшірмесін құрайды. Рекурсивтік функциядан шығуды қарастыру керек, онда жүйенің “тежеліп” (“зависание“) қалуы мүмкін.
Функция
Параметрлі айнымалы санды функцияны құру үшін, stdarg.h және varargs.h файлдарын пайдалану керек.
Кемінде бір параметрі болып және көп нүктемен (...) аяқталған параметрлері айнымалы сандағы функцияларды сипаттағанда, соңғы фиксирленген параметрден кейін көп нүкте алдыңда қайырма қою шарт емес. Мысалы:
void (int a, int b,...);
немесе
void f (int a, int b...);
Cи тілінде аргументтер айнымалы санымен жұмыс істеу үшін басқа ешқандай жағдайлар қарастырмайды, бірақ stdarg.h файлында параметрлері айнымалы санды функциялармен қолдау табатын жабдықтар бар:
тип va_list
макрос va_start(list, last_fixed)
макрос va_arg(list, arg_type)
макрос va_end(list)
va_start макросы фиксирленбеген параметрлерге ену (доступ) механизмінің инициализациясын шығарады, list - va_list типті айнымалы және last_fixed- соңғы фиксирленген параметр.
Фиксирленбеген параметрлерге тізбектелген ену va_arg макроспен орындалады, мұндағы макростың бірінші параметрі, va_start шақырумен инициализацияланған va_list типті айнымалы, ал екінші параметр - келесі параметрдің типі; va_arg бұл параметрдің мәнін қайтарады. Типтің сәйкестігін тексеру жүргізілмейді, яғни va_arg типімен және функцияны шақырудағы сол берген арасында сәйкестік программистің бақылауында болуы
керек.
va_end макросы va_list типті айнымалымен жұмысты аяқтайды.
Функцияны параметрлері айнымалы санды функцияны пайдаланудың мысалы:
1. int sum_1 (int a,...)
{ va_list args;
int result=a,t;
va_start (args, a);
while (t=va_arg (args, int)і=0)
result +=1;
va_end (args);
return result;}
2. int sum_2 (int num_args,...)
{ va_list args;
int result=0,i;
va_start (args, num_args);
for (i=0;i< num_args ;i++)
result +=va_arg(args,int);
va_end (args);
return result;}
void error_message (char*fint,....)
{va_list (args);
printf (“error:”);
va_start (args, fint);
vprintf (fint, args);
va_end (args);
exit (1);}
Мұнда параметрлері айнымалы санды функциямен жұмыс істеудің үш тәсілін келтірілген. Мұндағы негізгі проблема, шақырылатын функцияда параметрлердің типі де, олардың саныда белгісіз болуында. Келесі :
(printf () функциясындай форматтау қатары форматттау спецификасы арқылы параметрлердің толық типін және санын анықтайды.
(кейбір мәндерді (мысал 1) резервтелінген етуге болады.
(Параметрлер санын фиксирленген параметрлер (мысал 2) ретінде беруге болады.
(stdio.h файлында туысқандық функциялар vprintf () ,vsprintf (), vfprintf (), vscanf (),vsscanf (), vfscanf () қарастырылған. Оларды басқа параметрлері айнымалы санды функцияларда пайдалануға болады.
Бұл механизм қалай орындалады. Функцияның параметрлері жадыда бірінен соң бірі орналасады. Va_list типі - void көрсеткіші болады. va_start макросы бұл көрсеткішті соңғы фиксирленген параметрден кейін орнатады. va_arg макросы белгіленген екінші параметр ретіндегі типті пайдалануда, бірінші параметр көрсеткен мәнге қайтарады.
Borland C++ фиксирленбеген параметрлерді char, unsigned char тиянақты пайдалану керек. Өйткені жадыда оларға 1 байт орынды алады, ал стекте оларға 2 байт бөлінеді.
Егер кейбір операциялар жиынтығын бірнеше рет орындауға (бастапқы берілгендерді жиі жаңадан енгізу) тура келсе, онда ішкі программа деп аталатын программалық модуль қалыптастыруға болады. Си тілінде ішкі программаның бір ғана түрі -функция -қолданылады.
Ішкі программа -функциямен жұмыс істеу нәтижесінде, оның атымен байланысты кейбір мәндер қалыптасады. Сондықтан ішкі программаны анықтаған кезде, оның атының алдыңда, көрсеткіштің типі қойылады. Кейде, функцияны пайдаланудың логикасы, функцияның атымен байланысқан мәнді қалыптасуын қажет етпейді. Сонда типтің көрсеткіші ретінде void қызметші сөзі пайдаланады.
Си тілінде функцияның анықталуын (хабарлануын) және оның сипатталуын білуіміз керек. Егер функцияның бары туралы хабарланса, онда қалған функциялар (main деп аталатын бас функцияны қоса) функцияда хабарлануы мүмкін. Бірақ та функцияны хабарлау жеткіліксіз. Оның толық мәтінің сипаттауымыз керек.
Программаның басында пайдаланатын функциялардың анықталынуы берілген. Анықталуында параметрлердің типі және саны көрсетілген, бұл алдағы уақытта функцияны шақыру кезінде, әртүрлі қателерді (негізгі параметрлердің типімен санының сәйкес келмеуі) бақылауды қамтамасыз етеді. Содан кейін тұрақтылар сипатталады. Жалпы тұрақты функциядан тыс сипатталғандықтан, барлық функцияларға “көрініп“ тұр. Келесіде, әрдайым main деп аталатын бас функцияның тексті (сипатталуы) келеді. Программада мұндай функция - жалғыз және main функциясына назар аударып орындалады. Программаның текстінде main() кез келген жерінде орналасуы мүмкін. Қарастырылған программада main() кейін үш функция сипатталған: берілгендерді енгізу, нәтижені есептеу және оны шығару.
Inab функциясының орындалуының нәтижесі, оның атымен байланысты, бұл нәтиже пайдаланбайды, void типінің берілгені ретінде жүреді. Функцияның параметрлері, берілгендерді енгізетін орындарының адрестері болып табылады. Сондықтан кіретін параметрлер, float типті берілгендер сияқты анықталмайды. Ал, олар осы берілгендерге көрсеткіш түрінде анықталынады.
Result () функциясы бастапқы берілгендер ретінде сандық мәндерді және float типті нәтижені шығарады. Функцияның атымен байланысты нәтижені беру үшін, return операторы пайдаланады.
Outres () функциясы оның атымен байланысқан нәтижені шақыру “нүктесіне“ қайтармайды. Сондықтан, бұл функция void типті болады.
Функцияның анықталуы
Программада пайдаланатын функция анықталуы тиіс; басқаша айтқанда, олар “хабарланған“ болуы керек. Функцияның анықталуының екі тәсілі бар: классикалық
және қазіргі «современный». Классикалық тәсіл функцияның атын және нәтижені шақыру нүктесіне қайтаратын типті ғана хабарлайды. Жоғарыда қарастырылған программада:
void inab ();
float result ();
void outres ();
Мұнда параметрлердің саны, типтері туралы ешқандай информация жоқ.
“Қазіргі заманғы“ тәсіл прототип деп аталатын хабарлануды пайдаланады. “Прототип“ термині функцияны хабарлау кезінде, параметрлер туралы информацияны қосу үшін пайдаланады. Қарастырылған программада прототиптер, әрбір функцияның бірінші қатарын дәлме-дәл қайталайды. Жалпы жағдайда прототип мына форматқа бағынады:
функция-аты типі (инф-парам-1, ..., инф-парам-і,...);
мұндағы инф-парам-і- і-ші параметр туралы информация
Прототипті параметр туралы информация мына түрде көрсетіледі:
а) тип
параметр-атының типі
...
с) варианттың пайдалану параметрлері өзгеруі мүмкін екендігін білдіреді. Прототиптерді қолдану, параметрлердің тапсырмаларының корректілі ойылмағандығына, компиляторға бақылау жауапкершілігін жүктейді.
Достарыңызбен бөлісу: |