Գործառույթները C ծրագրավորման մեջ  


ներածություն  

Ենթադրենք, որ մենք պետք է ծրագիր գրենք `երկու թվեր մուտքագրելու և օգտագործողի կողմից թվաբանական գործողություն կատարելու համար: Օգտագործողը կարող է խնդրել թվաբանական գործողություններից որևէ մեկը, ինչպիսիք են գումարումը, հանումը, բազմապատկումը կամ բաժանումը: Ինչպե՞ս ենք ծրագիր գրելու: Մենք գրելու ենք հիմնական գործառույթով մեկ C ծրագիր, որտեղ ընդունելու ենք երկու թվեր և կատարվելիք գործողություն: Կախված օգտագործողի մուտքագրած գործողությունից, մենք կունենանք այն պայմանը, երբ կավելացնենք / հանենք / բազմապատկենք / բաժանենք թվերը: Սրանք ուղիղ առաջ քայլեր են այս պարզ պահանջի համար: Պատկերացրեք, որ այս գործողությունները երկու թվերի վրա ավելանում են ՝ ավելացնելով ավելի շատ թվեր կամ թվերի զանգված: Այնուհետև յուրաքանչյուր «եթե» արտահայտության ծածկագիրը նույնպես կավելանա: Դա նշանակում է, որ պահանջը փոխվելիս կամ բարդանում է, ծածկագիրը նույնպես ավելանում է և դառնում բարդ: Սա իր հերթին նվազեցնում է նաև կոդի ընթերցանությունը: Ի՞նչ կլինի, եթե մենք կատարենք այս գործողությունների շարքը անվանական բլոկում և զանգահարենք այս բլոկին, երբ դա պահանջվի: Այն մեծացնում է կոդի ընթերցանությունը, ինչպես նաև օգտվողին ստիպում է այն հեշտությամբ հասկանալ:

Օրինակ, թվերի զանգվածի համար նույն թվաբանական գործողությունները ստեղծվում են տարբեր գործառույթներում, ինչպիսիք են գումարումը (), հանումը (), բազմապատկումը () և բաժանումը () և հիմնական գործառույթը, եթե այդ գործառույթները կանվանենք «եթե» արտահայտության մեջ գործողություն, ապա ծածկագիրը կարծես ավելի պարզ և հեշտ է ընկալելի: Այս գործողությունների համար օգտագործվող տրամաբանությունն այստեղ պակաս կարևոր է: Եթե ​​մենք պետք է իմանանք տրամաբանությունը, ապա կարող ենք ստուգել համապատասխան գործառույթը: Ենթադրենք, բաժանման ժամանակ կա որևէ լրացուցիչ պահանջ `ստուգելու համար արդյոք բաժանարարը զրո է: Այդ դեպքում մենք չպետք է անցնենք ամբողջ հիմնական գործառույթը, մինչև ստանանք բաժանման գործողության ծածկագիրը: Փոխարենը մենք կարող ենք ուղղակիորեն բերել բաժնի () գործառույթը և զրոյի ստուգման համար ավելացնել նոր կոդերի շարք: Այսպիսով, գործառույթի ստեղծումը նոր պահանջի ավելացումը դարձնում է նաև ավելի պարզ: Հետևաբար, C գործառույթներում մեծապես օգտագործվում են:

C- ում ամեն ինչ գրված է ֆունկցիայի շրջանակներում: Itselfրագիրն ինքնին սկսում է հիմնական () գործառույթից: Ինչպես անունն է հուշում, դա ցանկացած ծրագրի հիմնական գործառույթն է, որից սկսվում է ծածկագրի կատարումը: Օգտագործողի այլ պահանջները այնուհետև բաժանվում են բազմաթիվ գործառույթների և կանչվում են հիմնական գործառույթից: Anyանկացած այլ գործառույթ կարող է նաև զանգահարել նույն կամ այլ գործառույթ: Մի խոսքով, C- ն առանց գործառույթների ամբողջական չէ:

Ֆունկցիան կարող է ընդունել մեկ կամ մի քանի մուտքեր, դրանց վրա ինչ-որ գործողություն կատարել, և կարող է արդյունքը վերադարձնել զանգահարող գործառույթին, թե ոչ: Այն կարելի է կանչել ցանկացած գործառույթից, ցանկացած քանակի անգամ: Դա նշանակում է, որ ֆունկցիան ծրագրի մեջ օգտագործված անվանումով բազմակի օգտագործման կոդ է:

Ֆունկցիայի տեսակները  

C- ում մենք ունենք երկու տեսակի գործառույթներ:

Գրադարանի գործառույթը

Գրադարանի գործառույթները ներկառուցված գործառույթներն են C. Ամենատարածված օգտագործվող ֆունկցիոնալությունները, ինչպիսիք են օգտագործողից մուտքագրումը, էկրանին ելքի ցուցադրումը, ցանկացած երկու տողի համեմատությունը, երկու տողի արժեքի պատճենումը, հիշողությունը հատկացնելը և այլն, արդեն ծածկագրված են տարբեր գործառույթների Գ և տեղադրվել է գրադարաններում: Այս գործառույթները կարելի է անվանել այնպես, ինչպես և երբ դրանք պահանջվում են մեր ծրագրում:

Օրինակ, մենք պետք է ստեղնաշարից անուններ մուտքագրենք: Դա նշանակում է, որ ծրագիրը պետք է կարդա ստեղնաշարի գրառումները և պետք է հնարավորություն ունենա պահելու որոշ փոփոխականում: Ֆունկցիան պետք է լինի բավականաչափ ճկուն ՝ տարբեր տեսակի փոփոխականներ ընդունելու համար: Այս բոլոր պահանջները նախապես մշակվում և դրվում են գործառույթ, որը կոչվում է scanf ():

Գրադարանի գործառույթների մի քանի այլ օրինակներ են `printf (), main (), strcpy (), strcmp (), strlen (), malloc () և այլն:

Գրադարանի այս գործառույթները կրկին դասակարգվում են ՝ ելնելով դրանց օգտագործման և ֆունկցիոնալությունից, և տեղադրվում են տարբեր ֆայլերում: Այս ֆայլերը հայտնի են որպես վերնագրի ֆայլեր: Այս ֆայլերը պահվում են '.h' ընդլայնումներով `նշելով վերնագրի ֆայլերը: Առավել հաճախ օգտագործվող մուտքային և ելքային գործառույթները տեղադրվում են stdio.h վերնագրի ֆայլում: Այս վերնագրի ֆայլում մենք կունենանք բոլոր հիմնական (), scanf, printf, ստացումները, getchar, տեղադրումները, putchar և այլն: Գրադարանի հետ կապված բոլոր գործառույթները տեղադրվում են string.h վերնագրի ֆայլում:

Երբ մենք ծրագիր ենք գրում, նա չի իմանա, թե որտեղ են այդ ներկառուցված գործառույթները կամ որտեղից վերցնել այդ գործառույթները: Մենք պետք է դրանք հստակ ներառենք մեր օրենսգրքում: Սա կօգնի կազմողին իմանալ գործառույթները, որոնք կօգտագործվեն ծրագրում, ինչպես նաև կխուսափի բոլոր ներկառուցված գործառույթները ներառել մեր կոդի մեջ: Սա մեզ թույլ է տալիս ներառել միայն այն վերնագրի ֆայլերը, որոնք պահանջվում են ծրագրի համար: Մենք կարող ենք օգտագործել միայն այն վերնագրի ֆայլերը, որոնք պահանջվում են ծրագրի կողմից: Վերնագրի այս ֆայլերը ավելացվում են մեր ծրագրին ՝ օգտագործելով «# ներառել» կոչվող նախամշակիչ հրահանգը, այսինքն.

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

Այս հրահանգները տեղադրվում են ծածկագրի սկզբում: Երբ կազմողը կազմում է կոդը և տեսնում այդ հրահանգները, այն ուղղակիորեն փոխարինում է նրանց համապատասխան ծածկագրով: Հետևաբար, երբ մենք կանչում ենք այնպիսի գործառույթներ, ինչպիսիք են scanf, printf և այլն, նա գիտի դրանց սահմանումը և կատարում է այդ կոդերը:

Տես նաեւ,
Պահպանման դասեր C ծրագրավորման մեջ

Օգտագործողի կողմից սահմանված գործառույթը

Սրանք օգտագործողի կողմից հայտարարագրված և սահմանված գործառույթներն են ՝ ըստ իրենց ծրագրի պահանջի: Այս գործառույթները մատչելի են միայն ընթացիկ ծրագրի համար, որում այն ​​սահմանված է: Այն կարող է օգտագործվել ծրագրի կողմից, որում սահմանված է, ինչպես նաև ծրագրի բոլոր հարակից ֆայլերը: Բայց այն չի կարող օգտագործվել որպես գրադարանի գործառույթ բոլոր ծրագրերում:

Երբ բլոկում կամ որևէ այլ ֆունկցիա կանչվում է մի ֆունկցիա, կատարման հսկողությունը կանցնի բջջային գործառույթին. այն կկատարի ֆունկցիայի մեջ գործող հայտարարությունները և հետ կվերադառնա կոչված բլոկ / ֆունկցիա ՝ առանց որոշ արժեքների

Վերևի գծապատկերից պարզ է դառնում, թե ինչպես է գործում ֆունկցիայի զանգը: Այն գործում է պիտակի պես, բայց դրա կատարումն ավարտելուց հետո այն վերադառնում է զանգահարող բլոկ:

Գործառույթների առավելությունները  

Այն մեծացնում է ծրագրի ընթեռնելիությունը, ինչպես նաև նվազեցնում է ծրագրի բարդությունը:

  • Եթե ​​կա կոդի կրկնվող բլոկ, ապա եթե այն տեղադրվում է ֆունկցիայի մեջ և կարող է կանչվել այնտեղ, որտեղ պահանջվում է: Դա ծրագիրը դարձնում է պարզ և հեշտ ընկալելի:
  • Այն գործառույթում օգտագործում է վերևից ներքև մոտեցում. Դա նշանակում է, որ նախ կատարում է գործառույթի բարձր մակարդակի բոլոր տրամաբանությունները, այնուհետև տեղափոխվում է ցածր մակարդակի տրամաբանություն: Եթե ​​նույնիսկ ավելի կոնկրետ լինենք, այն նախ խնդիրը բաժանում է տարբեր առաջադրանքների և ստեղծում գործառույթներ նրանց համար: Ավելի ուշ գործառույթի մեջ այն տրամաբանություն է ստեղծում այդ խնդիրները լուծելու համար: Օրինակ, գրեք ծրագիր թվաբանական գործողություններ կատարելու համար, ինչպիսիք են թվերը գումարել / հանել / բազմապատկել / բաժանել: Aրագիր գրելիս մենք տեսնում ենք, որ նախ միայն թվերը գումարվում / հանվում / բազմապատկվում / բաժանվում է և ստեղծվում է համապատասխան գործառույթ: Այս գործողությունների կատարման ավելի մանրամասն մանրամասները, որոնք գործողությունների ցածր մակարդակներն են, կատարվում են համապատասխան գործառույթների շրջանակներում:
  • Մենք կարող ենք նորից օգտագործել գործառույթները նույն ծրագրում կամ նույն օգտվողի կողմից գրված այլ ծրագրերում: Մենք նույնիսկ կարող ենք ստեղծել գործառույթներ, որոնք կարող են կրկին օգտագործվել այլ ծրագրերի, այլ օգտագործողների կամ նույնիսկ այլ համակարգերում:
  • Այն օգնում է լավ հասկանալ ծրագրի տրամաբանությունը և գործել: Բացի այդ, դա ավելի հեշտ է դարձնում կարգաբերման գործառույթը, քան մեկ կոդի ամբողջ երկարությամբ կարգաբերման սխալը: Օրինակ, եթե բաժնի () ֆունկցիայի մեջ կա որևէ սխալ, ապա մենք կարող ենք ուղղակիորեն անցնել գործառույթ և լուծել խնդիրը: Բայց եթե այդպիսի գործառույթ չկար, և ամբողջ երկարության կոդ էր գրված, ապա մենք ի վերջո կհայտնաբերենք լրիվ ծածկագիրը կարգաբերելու մեջ: C- ը մեզ թույլ է տալիս կազմել և կարգաբերել միայն գործառույթները, այլ ոչ թե կազմել ամբողջ ծրագիրը: Սա նաև լրացուցիչ առավելություն է ՝ կոդերը կարգաբերելու համար: Սա ավելի հեշտացնում է թեստավորումը:

Գործառույթի հայտարարագրեր  

Օգտատիրոջ կողմից սահմանված գործառույթը պետք է ծածկագրվի օգտագործողի / մշակողի կողմից և այն ունի հատուկ ձևաչափ, որը C կազմողը կարող է հասկանալ: Որպես գործառույթ ստեղծելու առաջին քայլ, մենք պետք է հայտարարենք դրանք: Այն համարժեք է RAM- ում հիշողության տարածություն ստեղծելուն ՝ ֆունկցիան պահելու և գործառույթի տարբեր առաջադրանքներ կատարելու համար: Տիպիկ գործառույթը հիմնականում ունի երկու մաս ՝ ֆունկցիայի վերնագիր և ֆունկցիայի մարմին: Ֆունկցիայի վերնագիրը գործառույթի առաջին տողն է, որը նշում է ֆունկցիայի անվանումը, գործառույթին փոխանցված արգումենտները և գործառույթի վերադարձման տեսակը: Մի խոսքով, ֆունկցիայի վերնագիրը պատմում է ֆունկցիայի կառուցվածքը:

Երբ ծրագրում ստեղծում ենք գործառույթ, մենք հայտարարում ենք գործառույթ իր վերնագրով: այսինքն;

datatype function_name (փաստարկներ / պարամետրեր);

Այստեղ տվյալների տիպը գործառույթի ելքի տվյալների տիպն է: Դա կարող է լինել ցանկացած պարզունակ կամ ոչ պարզունակ տվյալների տիպ: Դա կարող է նույնիսկ անվավեր լինել ՝ ցույց տալով, որ այն չի վերադարձնում որևէ արդյունք: Հաջորդը գործառույթի անունն է: Սովորաբար իմաստալից անուն է տրվում, որպեսզի անունը տեսնելով ՝ կարելի է հասկանալ, թե ինչ է գործառույթը անում: Ֆունկցիայի անվանումը պետք է բացառիկ լինի ծրագրին: Նույն ծրագրի ոչ մի այլ գործառույթ չպետք է ունենա նույն գործառույթի անվանումը: Հաջորդը փաստարկների / պարամետրերի ցանկն է: Սրանք զանգահարող գործառույթից գործառույթին փոխանցված կամ առանց արժեքների փոփոխականներ են: Ֆունկցիան նույնպես կարող է լինել առանց որևէ փաստարկի: Եթե ​​մենք փոխանցենք փաստարկները, ապա պետք է նշենք դրանցից յուրաքանչյուրի տիպերը: Մենք կարող ենք ցանկացած թվով փաստարկներ փոխանցել գործառույթին:

անվավեր fn ispուցադրել (կառք chrString []); // տողի պարամետրով գործառույթ ՝ առանց վերադարձի արժեքների
int fnAddition (int intNum1, int intNum2); // ֆունկցիա ՝ 2 ամբողջ թվով արգումենտներով, ամբողջ թվային արտադրանքով
բոց fnAverage (int intum []); // գործառույթ ՝ որպես ամբողջ զանգված, փաստարկով, վերադարձի արժեքով ՝ որպես բոց

Դրանք տարբեր ֆունկցիաների հայտարարագիր են ՝ կախված պահանջից, մուտքային պարամետրերից և դրանց վերադարձման արժեքներից: Ֆունկցիայի հայտարարագիրը կատարվում է նախքան այն սահմանված և օգտագործված է ծածկագրում: Սովորաբար մենք գործառույթը հայտարարում ենք նախամշակիչ հրահանգներից անմիջապես հետո:

#include <stdio.h>

//Function Declaration
void fnDisplay (char chrString []); // a function with string parameter with no return values
int fnAddition (int intNum1, int intNum2); // a function with 2 integer arguments with integer output
float fnAverage (int intNum []); // a function with argument as integer array with return value as float

void main (){
// example program
}

Ֆունկցիայի սահմանումներ  

Ֆունկցիայի մարմինը իրենից փոխանցված պարամետրերն օգտագործող հայտարարությունների և արտահայտությունների կոդի ամբողջություն է: Այն սահմանում է ֆունկցիայի ֆունկցիոնալությունը: Մենք կարող ենք ֆունկցիայի սահմանում տեղադրել գործառույթը հայտարարելիս կամ ծրագրի ցանկացած կետում:

Տես նաեւ,
Հիմնաբառեր C ծրագրավորման մեջ

Ֆունկցիայի բնորոշ սահմանումը ներառում է ֆունկցիայի վերնագիր, որին հաջորդում է բաց փակագիծը `'{': Գործառույթի մարմնում մենք կարող ենք ունենալ ֆունկցիայի տեղական փոփոխականների հայտարարագիր, առաջադրանքները կատարելու համար ծածկագիր և վերադարձի հայտարարություն ՝ զանգը գործառույթին վերադարձնելու համար, որին հաջորդում է փակ փակագիծը ՝ '}':

datatype function_name (arguments/parameters) {
	declaration part;
	expressions/ statements;
	return variable_name;
}

Սա ֆունկցիայի մարմնի բնորոշ կառուցվածքն է C լեզվով: Ստորև բերված է ծրագրի օրինակ, որը ցույց է տալիս, թե ինչպես է ծրագրի կառավարումը ցատկում, երբ գործառույթ է կանչվում: Այստեղ գործառույթի սահմանումը տեղադրվում է ծածկագրի վերջում: Բայց մենք գործառույթը հայտարարել ենք նույնիսկ հիմնական գործառույթի մեկնարկից առաջ: Երբ կոմպիլյատորը կազմում է ծածկագիրը, նա տեսնում է հայտարարությունը և հասկանում է, որ դրա համար կա սահմանում: Երբ գործառույթը կանչում ենք հիմնական գործառույթում, այն փոխարինում է ֆունկցիայի զանգը ֆունկցիայի սահմանմամբ և կատարում է կոդը: Եթե ​​մենք սկզբից ֆունկցիան չհայտարարեինք և այն կանչեինք հիմնական ֆունկցիայի մեջ, ապա կազմողը չի իմանա, որ ֆունկցիան վերջում է սահմանված, և նետում է կազմման սխալը, որը սահմանված չէ: Մենք կարող ենք նույնիսկ տեղադրել գործառույթի սահմանումը `միաժամանակ հայտարարելով ինքն իրեն:
#include <stdio.h>
void fnDisplay (char chrString []); // a function with string parameter with no return values

void main (){
	char chrStr [] = "Example of a Function";
	printf ("\nBefore calling the Function.....");
	fnDisplay (chrStr); // calling the function
	printf ("\nAfter calling the function.....");
}

// Function definition
void fnDisplay (char chrString []){
	printf ("\nInside the function Body......\n");
	printf ("%s", chrString);
	printf ("\nEnd of the function Body.....");
}

Callանգահարելու գործառույթներ  

Մենք սովորել ենք, թե ինչպես հայտարարել գործառույթը և սահմանել դրա սահմանումը: Այժմ տեսնենք, թե ինչպես կարելի է ֆունկցիան կանչել մեկ այլ գործառույթից: Ֆունկցիան կարելի է կանչել ցանկացած գործառույթից / ծածկագրից `նշելով դրա անունը: Բացի այդ, այն պետք է համապատասխանի գործառույթի սահմանմանը. Սա նշանակում է, որ եթե գործառույթն իրեն փոխանցել է պարամետրեր, ապա մենք պետք է պարամետրերը փոխանցենք գործառույթին ՝ նշելով դրանք փակագծերում '()': Պարամետրերի տեսակը պետք է ճշգրիտ համընկնի գործառույթում հայտարարված տիպի հետ: Գործառույթին փոխանցված փոփոխական անունները և ֆունկցիայի հայտարարագրում նշված անունները կարող են տարբեր լինել: Բայց պարամետրերի քանակը և դրանց տեսակը միշտ պետք է համապատասխանեն:

fn ispուցադրել (chrStr); // գործառույթը կանչելը

Այստեղ ֆունկցիան ընդունում է մեկ փաստարկ և տողի տիպ է: Ֆունկցիան զանգահարելիս մենք անցնում ենք նույն տեսակի պարամետրը: Կարելի է զարմանալ, թե ինչու է միայն փոփոխականի անունը փոխանցվում որպես պարամետր: Այստեղ տողը բնույթի զանգված է, և զանգվածը գործում է ցուցիչի պես. Երբ զանգվածի անունը նշվում է, այն ցույց է տալիս զանգվածի առաջին տարրը: Ուստի լարը փոխանցվում է գործելու ինչպես ցանկացած այլ նորմալ փոփոխական: Նույնի մասին ավելի մանրամասն `ցուցիչի բաժնում: Եթե ​​մենք անցնում ենք փոփոխականի որևէ այլ տիպ, ապա մենք արժեքը փոխանցում ենք ֆունկցիայի պարամետրին ՝ նշելով փոփոխականի անունը:

fnAddition (intVal1, intVal2);

Այստեղ intVal1- ը և intVal2- ը ամբողջ տեսակի են, և դրանք վերևի նման փոխանցվելիս դրանց անունները փոխարինվում են դրանց արժեքով: Հետևաբար, երբ այս զանգը փոխարինվում է դրա սահմանմամբ, կազմողը ստանում է արժեքը համապատասխանաբար intNum1 և intNum2:

Եթե ​​ֆունկցիան վերադարձնում է արժեքը, ապա ֆունկցիայի կանչը պետք է նշանակվի փոփոխականին, որը վերադարձի տիպ է: FnDisplay գործառույթում վերադարձի տեսակը անվավեր է: Հետևաբար, անհրաժեշտ չէ ֆունկցիայի կանչը նշանակել ցանկացած փոփոխականի: FnAddition գործառույթում այն ​​արդյունքը վերադարձնում է զանգահարող գործառույթին: Հետևաբար, մենք պետք է որևէ արդյունք գրանցենք նույն տիպի որոշ փոփոխականի մեջ: Հետևաբար, գործառույթն անվանում ենք ստորև.

intResult = fnAddition (intVal1, intVal2); // կոչ է անում գործառույթը

 

#include <stdio.h>
int fnAddition(int intNum1, int intNum2);

void main(){
	int intVal1, intVal2, intResult;

	printf("\nPlease enter first number to be added:");
	scanf("%d", &intVal1);
	printf("\nPlease enter second number to be added:"); 
	scanf("%d", &intVal2);
	intResult = fnAddition(intVal1, intVal2); //calls the function
	printf("\nSum of two number is:%d", intResult);
}
// Function definition
int fnAddition (int intNum1, int intNum2){
	return intNum1 + intNum2; // returns the sum of two numbers
}

Ֆունկցիայի պարամետրերը  

Մենք գիտենք, թե որոնք են գործառույթների պարամետրերը: Բայց ինչպես փոխանցել պարամետրերը գործառույթին և ինչպես են դրանց արժեքները նշանակվելու ֆունկցիայի պարամետրերին դրա սահմանման մեջ: Ֆունկցիայի հայտարարագրում հայտարարված պարամետրերը կոչվում են ֆորմալ պարամետրեր: Դրանք ստեղծվում են, երբ ֆունկցիան կանչվում է և գործում է որպես տեղական փոփոխական գործառույթի շրջանակներում: Գործառույթն ավարտելիս դրանք ջնջվում են հիշողությունից: Այն նորից կստեղծվի հիշողության որևէ այլ վայրում, եթե նույն գործառույթը կրկին կանչվի:

int fnAddition (int intNum1, int intNum2); // intNum1 and intNum2 are formal parameters
void fnDisplay (char chrString []){//chrString[] is formal parameter
	printf ("\nInside the function Body......\n");
	printf ("%s", chrString);
	printf ("\nEnd of the function Body.....");
}

Ֆունկցիան զանգահարելիս գործառույթին փոխանցված պարամետրերը / փոփոխականները կոչվում են որպես ֆունկցիայի իրական պարամետրեր: Նրանք ունեն ֆունկցիայի պարամետրերի իրական արժեքները և կախված դրանց արժեքից `գնահատվում է գործառույթը: Իրական և պաշտոնական պարամետրերի ծածկագրերի անվանումներում կարող են լինել նույնը կամ տարբեր: Մենք դրանք տարբեր ենք պահում ՝ դրանք տարբերակելու համար:

Տես նաեւ,
Static Storage Class C mingրագրավորման մեջ

fnDisplay (chrStr); // chrStr- ը փաստացի պարամետր է
intResult = fnAddition (intVal1, intVal2); // intVal1- ը և intVal2- ը իրական պարամետրերն են

Գործառույթին անցնող իրական պարամետրերը փոխանցելու երկու եղանակ կա:

  • Անցնել արժեքով

Այս մեթոդով, երբ գործառույթ է կանչվում, իրական պարամետրերը կունենան գնահատման իրական արժեքներ: Երբ կազմողը փոխարինում է ֆունկցիայի զանգը իր սահմանմամբ, դրա պաշտոնական պարամետրերը փոխարինվում են արժեքներով: Քանի որ պաշտոնական պարամետրը դրանց արժեքն է ստանում, ֆորմալ պարամետրի փոփոխականի ցանկացած փոփոխություն չի փոխի իրական պարամետրի փոփոխականի արժեքը: Դա կարող է ազդել գործառույթի ներսում, բայց զանգահարող գործառույթին վերադառնալիս պարամետրի իրական արժեքը կմնա անփոփոխ:

intResult = fnAddition (intVal1, intVal2); // intVal1- ը և intVal2- ը պարամետրերի իրական արժեքն են

երբ կոմպիլյատորը կազմում է ծածկագիրը, այն փոխարինում է վերը նշված գործառույթի զանգին, ինչպես ստորև ՝
Ենթադրենք, intVal1 = 10 և intVal2 = 40, ուրեմն
intResult = fn Լրացում (10, 40);

int fnAddition (10, 40){
	return 10 + 40; // returns the sum of two numbers
}

Այստեղ մենք չենք ձևափոխել ֆորմալ պարամետրը, ուստի ֆունկցիայի սահմաններում արժեքների փոփոխություններ չկան: Հետևաբար, իրական պարամետրերում նույնպես փոփոխություններ չկան:

Ենթադրենք, որ մենք ունենք ներքևի նման մեկ այլ գործառույթ, որը պարզապես ավելացնում է 10-ով փոխանցված պարամետրի արժեքը: Ենթադրենք, intVal- ն ունի 25 արժեք:

intResult = fnIncrement (intVal); // intVal- ը փաստացի պարամետր է

Երբ գործառույթը կանչվում է վերևում, կոմպիլյատորը դա տեսնում է այսպես

intResult = fn Մեծացում (25); // intVal- ը փաստացի պարամետր է

Այն փոխարինում է այս զանգը գործառույթի սահմանմամբ, ինչպես ստորև.

 

Ստորև ներկայացված ծրագրում մենք կարող ենք տեսնել իրական և պաշտոնական պարամետրերի նույն ազդեցությունը: Գործառույթից հետո մենք կարող ենք նկատել, որ իրական պարամետրի արժեքը չի փոխվում, չնայած ֆունկցիայի մեջ պաշտոնական պարամետրի արժեքը փոխված է: Չնայած պաշտոնական պարամետրը փոխարինվում է փոխանցված արժեքով, այն գործում է որպես ֆունկցիայի շրջանակներում տեղական փոփոխական: Դրա արժեքը անհետանում է հենց գործառույթն ավարտվելուն պես:

#include <stdio.h>
int fnIncrement (intVal);

void main (){
	int intVal=25, intResult;

	printf ("\nValue of intVal before function call is %d", intVal);
	intResult = fnIncrement(intVal); //calls the function
	printf ("\nValue of intVal after function call is %d", intVal);
	printf ("\nIncremented Value is:%d", intResult);
}
// Function definition
int fnIncrement (int intNum){
	printf ("\nValue of intNum before incrementing is %d", intNum);
	intNum += 10;
	printf ("\nValue of intNum after incrementing is %d", intNum);
	return intNum;
 }

  • Անցեք հղումով

Այս մեթոդով մենք փոխանցում ենք փաստացի փոփոխականի հասցեն, որտեղ պահվում է փոխանցվող արժեքը: Դա նշանակում է, որ փոխանցվում է արժեքին հղում, որը դրա իրական արժեքը չէ: Հետևաբար, այստեղ և՛ ֆորմալ, և՛ իրական պարամետրերը մատնանշելու են հիշողության նույն վայրերը: Այսպիսով, պաշտոնական կամ իրական պարամետրի ցանկացած փոփոխություն կփոխի և՛ արժեքները: Սա նշանակում է, որ երկու պարամետրերով նշված հասցեն մնում է նույնը, բայց այդ հասցեի արժեքը կարող է փոխվել ցանկացած արժեքի:

Հաշվի առեք վերը նշված նույն ավելացման ծրագիրը: Եկեք պարամետրը փոխանցենք հղումով - գործառույթը զանգահարելիս փոխանցեք intVal- ի հասցեն որպես պարամետր: Այնուհետև intNum ֆորմալ պարամետրը ստանում է նաև intVal- ի հասցեն, ուստի երկուսն էլ այժմ վերաբերում են նույն արժեքին:

#include <stdio.h>
int fnIncrement (int *intNum); // formal parameter needs to be a pointer, inorder to accept the address

void main (){
	int intVal = 25, intResult;

	printf ("\nValue and Address of intVal before function call is %d and %x", intVal, &intVal);
	intResult = fnIncrement (&intVal); //pass by reference
	printf ("\nValue and Address of intVal after function call is %d and %x", intVal, &intVal);
	printf ("\nIncremented Value and address of intResult is:%d and %x", intResult, &intResult);
}
// Function definition
int fnIncrement (int *intNum){// even though address is passed, the '*' now points to the value at the address passed
	printf ("\nValue and Address of intNum before incrementing is %d and %x", *intNum, intNum);
	*intNum += 10; // inorder to increment the value at the address passed, pointer notation needs to be used. Address of the variable remains same
	printf ("\nValue and Address of intNum after incrementing is %d and %x", *intNum, intNum);
	return *intNum; //returns the incremented value
}

Programրագրում մենք կարող ենք նկատել, որ գործառույթը հայտարարվում է ցուցիչի փոփոխականով: Poուցանիշի փոփոխականը ցույց է տալիս մեկ այլ փոփոխականի հասցեն: Հետևաբար, երբ մենք իրական պարամետրի հասցեն փոխանցում ենք ֆունկցիայի զանգին, պաշտոնական պարամետրին, intNum- ը ստեղծվում է intVal- ը մատնանշելու համար: Գործառույթում, երբ intNum- ը ավելացնում ենք 10-ով, մենք ենթադրաբար ավելացնում ենք intNum- ի արժեքը, բայց ոչ հասցեն: Ուստի մենք օգտագործում ենք '*' intNum- ից առաջ: Այսպիսով, intNum- ի կողմից նշված հասցեն մնում է անփոփոխ, չնայած որ արժեքը փոխվում է: Ավելացումից հետո intNum- ը և intVal- ը կունենան նույն արժեքը և հասցեն: Քանի որ մենք արժեքը վերադարձրել ենք զանգահարելու գործառույթին (նկատենք այստեղ, որ մենք չենք վերադարձրել հասցեն, բայց արժեքը), intResult- ը արժեքը կստանա տարբեր հասցեներում: Ենթադրենք, որ մենք վերադարձրել ենք intNum- ի հասցեն, ապա intResult- ը նույնպես ցույց կտար նույն հասցեն:

Տես նաեւ,
Գրանցեք պահեստավորման դասը C ծրագրավորման մեջ

Ստորև բերված ծրագիրը ցույց է տալիս, թե ինչպես կարելի է intResult- ը ստանալ նաև նույն հասցեում: Այս բոլոր պարամետրերն օգտագործում են ցուցիչներ: Այս փուլում դա կարող է շատ բարդ տեսք ունենալ, բայց պարզ կլինի, երբ ցուցիչը հասկանա: Միշտ հիշեք, որ * Num- ը նշում է արժեքը մեկ այլ հասցեի վայրում, Num- ը նշում է այլ վայրի հասցեն, իսկ & Num- ը `իր սեփական հասցեն: Բայց խնդրում ենք նկատի ունենալ, թե ինչպես է գործառույթը հայտարարվում, կոչվում, ինչպես են արժեքները փոխանցվում, վերադարձվում և ցուցադրվում:

#include <stdio.h>
int *fnIncrement (int *intNum); // formal parameter needs to be a pointer, inorder to accept the address

void main () {
    int intVal = 25,*intResult;

    printf ("\nValue and Address of intVal before function call is %d and %x", intVal, &intVal);
    intResult = fnIncrement (&intVal); //pass by reference
    printf ("\nValue and Address of intVal after function call is %d and %x", intVal, &intVal);
    printf ("\nIncremented Value and address of intResult is:%d and %x", *intResult, intResult);
}
// Function definition
int *fnIncrement (int *intNum){// even though address is passed, the '*' now points to the value at the address passed
    printf ("\nValue and Address of intNum before incrementing is %d and %x", *intNum, intNum);
    *intNum += 10; // inorder to increment the value at the address passed, pointer notation needs to be used. Address of the variable remains same
    printf ("\nValue and Address of intNum after incrementing is %d and %x", *intNum, intNum);
    return intNum; //returns the incremented value
}

Ֆունկցիաների այս տիպի հատկությունները հիմնականում օգտագործվում են այն ժամանակ, երբ մենք պետք է կրկնօրինակենք երկու արժեք, փոխենք երկու թվեր և այլն:

Variadic գործառույթները  

Երբեմն մենք կարող է չգիտենք փոխանցվող պարամետրերի քանակը և դրանց տվյալների տեսակները: Նման իրավիճակներում մենք կարող ենք ֆունկցիաներ ստեղծել կամընտրանքային պարամետրերով: Բայց մենք պետք է գոնե մեկ պարամետր փոխանցենք հայտնի տվյալների տիպով: Քանի որ ֆունկցիան ընդունում է փաստարկների / պարամետրերի փոփոխական քանակը, ֆունկցիան կոչվում է Variadic ֆունկցիա: Նման գործառույթը հայտարարելու ընդհանուր շարահյուսությունը ստորև.

datatype function_name (տվյալների տիպի փաստարկ 1,…);

int fn Լրացում (int intCount,…);

Այստեղ «…» նշանակում է կազմողը, որ այն ունի ցանկացած տեսակի և ցանկացած համարի ընտրովի փաստարկներ: Գործառույթում մենք դիմում ենք կամընտիր պարամետրերին ՝ օգտագործելով մակրոներ, ինչպիսիք են va_start, va_list և այլն: Այս մակրոները սահմանված են stdarg.h վերնագրի ֆայլում, և մենք պետք է ներառենք այս ֆայլը, եթե օգտագործում ենք փոփոխական գործառույթներ: Ֆունկցիայի հայտարարագրման և սահմանման առաջին փաստարկը պարտադիր է: Սովորաբար այս առաջին փաստարկը կլինի այս գործառույթին փոխանցված փաստարկների քանակը: Երբ գործառույթը կանչում ենք, մենք նշում ենք, թե քանի փաստարկ է անցնելու, որին հաջորդում է փաստացի ցուցակի ցուցակը: Այսպիսով, գործարկման ժամանակ ֆունկցիայի կանչը իմանում է, թե քանի փաստարկ է փոխանցվում դրան:

Այն օգտագործում է որոշ մակրոներ, որոնք օգտագործվում են փոխանցված փոփոխական փաստարկները ֆիքսելու, յուրաքանչյուր փաստարկը մշակելու և այլնի համար:

  • va_list: Սա գրադարանի փոփոխական է, որն օգտագործվում է փոփոխական գործառույթին փոխանցված փաստարկները պահելու համար: Մենք հայտարարում ենք va_list տիպի փոփոխական `ֆունկցիան անցած փաստարկները գրավելու համար:

   va_list փոփոխական_անուն;
  va_list պարամետրեր; // հռչակել va_list տիպի փոփոխական «պարամետրեր»

Գրադարանի այս փոփոխականը հարմար է մակրոների համար այն փոփոխականները պահելու համար, որոնք օգտագործվում են va_start, va_end և va_arg փոփոխական գործառույթների կողմից:

  • va_start: Սա մակրո է, որն օգտագործվում է պարամետրերի փոփոխական ցանկը va_list- ի կողմից հայտարարված փոփոխականին սկզբնավորելու համար: Այս մակրոը ֆիքսում է գործառույթին անցած բոլոր պարամետրերը va_list տիպի փոփոխականի և մատնանշում է փաստարկների ցուցակի սկիզբը: Այս մակրոը տանում է երկու արգումենտ. Մեկը va_list տիպի պարամետրերի ցուցակի փոփոխականն է, և մյուսը ՝ վերջին փաստարկը, որն առաջին ֆիքսված փաստարկն է, որը փոխանցվել է ֆունկցիային վերջին փաստարկ):

va_start (va_list arg_list, last_arg);
va_start (պարամետրեր, intCount); // Սկզբից սկսում է մուտք գործել ընտրովի պարամետր

Այստեղ «պարամետրերը» նախաձևավորվելու են ՝ գործառույթի զանգին փոխանցված պարամետրերի փոփոխական ցուցակը ունենալու համար: «intCount» - ը ֆունկցիայի վերջին փաստարկն է, որն այստեղ է ՝ գործառույթին փոխանցված մի շարք փաստարկներ:

  • va_arg: Այս մակրոը օգտագործվում է պարամետրերի ցուցակից հաջորդ փաստարկը ստանալու համար:

     type va_arg(va_list arg_list, type));

Այն անցնում է փաստարկների ցուցակի յուրաքանչյուր փաստարկ իր տվյալների տեսակով `որպես« տեսակ »: Մենք չգիտենք գործառույթին փոխանցված պարամետրերի համարը և տվյալների տեսակը: Հետևաբար, մենք պետք է որոշակի տվյալների տիպ նշանակենք անցած փաստարկներին, և օգտագործողը հստակորեն սահմանում է այն փաստարկների տեսակը, որոնք ստացվում են ՝ օգտագործելով va_arg մակրո: Այն վերադարձնում է փաստարկը, որը նույն «տիպի» է, որ ունի va_arg մակրո-ն:

intParam = va_arg(պարամետրեր, int));// առբերում է պարամետրերը «պարամետրերից» և գցում դրանք «int» տիպի և վերագրում այն ​​«intParam» փոփոխականին, որը նույնպես «int» տիպ է:

  • va_end: Այս մակրոտն օգտագործվում է գործառույթի պարամետրերի ցուցակի օգտագործման ավարտը ցույց տալու համար: Եթե ​​այս մակրոը չկանչվի, գործառույթը չի վերադարձվի, և դրա արդյունքը չի սահմանվի: Չնայած va_end մակրոը ոչինչ չի վերադարձնում, մենք պետք է նշենք այս մակրոը ՝ ֆունկցիայի փոփոխական պարամետրերի օգտագործման ավարտը ցույց տալու համար:
Տես նաեւ,
Հաստատություններ C ծրագրավորման մեջ

    va_end(va_list arg_list); // ավարտել պարամետրերի օգտագործումը
    va_end(պարամետրեր); // ավարտել պարամետրերի օգտագործումը

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

// Function declaration and definition
int fnAddition (int intCount, ...){
	int intSum = 0;
	va_list parameters; // declare a variable 'parameters' of type va_list

	va_start (parameters, intCount); //Starts accessing the optional parameter from the beginning
	printf("\nNumber of parameters passed is:%d", intCount);

	printf("\nNumbers that are passed to the function are:\n");
	for (int index = 0; index < intCount; index++)
		printf("%d\t", va_arg(parameters, int));

	va_start(parameters, intCount); //Starts accessing the optional parameter from the beginning
	for (int index = 0; index < intCount; index++)
		intSum += va_arg(parameters, int);
	
	va_end(parameters); // end the use of parameters
	return intSum; //return the result
}

void main (){
	int intResult;
	intResult = fnAddition (5, 10, 20, 30, 40, 50); //calls the function 5 parameters
	printf ("\nSum the numbers is:%d", intResult);
}

Հիմնական գործառույթը  

Սա ցանկացած C ծրագրի կարևոր գործառույթն է: Defaultանկացած ծրագիր պետք է իր մեջ ունենա այս լռելյայն գործառույթը: Այս ֆունկցիան այն է, որից սկսվում է C ծրագրի կատարումը: Հետևաբար, մենք չպետք է հայտարարենք ֆունկցիայի նախատիպը, բայց պետք է սահմանենք այս ֆունկցիան: Դա նշանակում է, որ մենք պետք է ունենանք այս հիմնական գործառույթը, որտեղ մենք ընդունում ենք արժեքները, կանչում ենք գործառույթները, ցուցադրում ենք արդյունքները և այլն: Հիմնական գործառույթը սովորաբար ունի վերադարձի տիպ ՝ որպես int, որն օգտագործվում է ծրագրի կարգավիճակը կազմողին ցույց տալու համար: Եթե ​​մենք օգտագործում ենք դրա վերադարձի տեսակը որպես int, ծրագիրը պետք է ունենա 'return 0;' վերջում նշելու համար ծրագիրը հաջողությամբ կազմվել է: Բայց մենք կարող ենք նաև դրա վերադարձի տեսակը անվավեր համարել ՝ նշելով, որ կազմողին կարգավիճակ չկա:

Այս ֆունկցիան կարող է փաստարկներ ունենալ կամ չունենալ: Փաստարկները փոխանցվում են գործառույթին, երբ ծրագիրը կատարելու ընթացքում անհրաժեշտ է հրամանը տողի միջոցով գրավել մուտքերը: Եթե ​​օգտագործողը ծրագիրը կատարելու ընթացքում մուտքագրում է մուտքագրում, ինչպես բոլոր օրինակներից վերևում, մենք չպետք է փաստարկները փոխանցենք հիմնական գործառույթին:

#include <stdio.h>

int main (){
	printf ("\Example of main function without arguments");

	return 0; // indicates compiler that program is executed successfully and can exit from the program
}

Երբ արգումենտները փոխանցվում են հիմնական գործառույթին, այն ընդունում է երկու արգումենտ ՝ մի ամբողջ թվով արգումենտների մի շարք, իսկ մյուսը ՝ char տիպի պարամետրերի զանգված: Այն կարելի է անվանել ցանկացած, բայց դրանք պետք է ունենան տվյալների նույն տեսակը, ինչպես բացատրվել է:

int հիմնական (int վեճ, կառք * argv []) {….}

վեճ - գործառույթին փոխանցվող պարամետրերի քանակն է

* արգվ [] - փաստերի զանգվածի նիշերի ցուցիչն է: Այն իր զանգվածում կընդունի արգումային քանակի պարամետրեր:

#include <stdio.h>

int main(int argc, char *argv[]){

	printf("\nTotal Number of arguments passed is : %d", argc);
	printf("\nArguments passed through command line is : \n");
	for (int index = 0; index<argc; index++)// traverses each arguments one by one
		printf("%s\t" , argv[index]);

	return 0; // indicates compiler that program is executed successfully and can exit from the program
}

Ռեկուրսիվ գործառույթներ  

Սրանք այն գործառույթներն են, որոնք կանչվում են նույն գործառույթի շրջանակներում բազմիցս: Դա նշանակում է, որ ֆունկցիան կոչվում է ինքնին:

datatype fn_name (){
	….
	fn_name(); // same function is being called
	….
}


Հետադարձ ֆունկցիայի բացատրության հայտնի օրինակը համարի ֆակտորալն է: Թվի ֆակտորալը `թվերի արտադրյալն է և թիվ 1-ի գործոնը: այսինքն;
գործոնային (n) = n * գործոնային (n-1)
= n * (n-1) * գործոնային (n-2)
=
= n * (n-1) * (n-2) *… .. * 3 * 2 * գործոն (1)
= n * (n-1) * (n-2) *… .. * 3 * 2 * 1
Այստեղ մենք կարող ենք դիտարկել օրինակը ՝ համարի ֆակտորիալը հաշվարկելիս: Այսինքն ՝ բազմիցս հաշվարկում է նախորդ թվի ֆակտորալը և բազմապատկում այն ​​ընթացիկ թվի հետ: Դա նշանակում է, որ երբ մենք գործառույթ ենք գրում ֆակտորալը հաշվարկելու համար, պետք չէ որևէ բան գրել օղակի կամ իսկ հանգույց որտեղ մենք անընդհատ բազմապատկում ենք թվերը ՝ գործոն ստանալու համար: Փոխարենը, մենք կարող ենք բազմիցս զանգահարել նույն գործառույթը, մինչև ստանանք թիվ 1: Մի խոսքով, գործոնային գործառույթը նման կլինի ստորև.
int fnFactorial(int intNum){
	if (intNum < 1)
		return 1;
	else
		return (intNum * fnFactorial(intNum - 1));
}

Քանի որ ֆունկցիան կանչվում է նույն ֆունկցիայի շրջանակներում, մենք պետք է զգույշ լինենք ռեկուրսիվ ֆունկցիա ստեղծելու համար: Եթե ​​պատշաճ դադարեցման հրաման չի օգտագործվում, այն կարող է հայտնվել անսահման օղակում: Վերոնշյալ օրինակում կա պայման ՝ ստուգելու համարը մեկից պակաս է: Եթե ​​դա մեկից պակաս է, ապա մենք այնտեղ գործառույթը չենք կոչում. փոխարենը վերադարձնելով 1 ՝ դադարեցնելով գործառույթի զանգը: Բայց եթե համարը մեկից մեծ է կամ հավասար է, մենք անընդհատ կանչում ենք intNum -1 համարի համարի գործառույթը: Այս կերպ այն հետ է բերում գործառույթը և կանգ է առնում մի կետում:
#include <stdio.h>
int fnFactorial(int intNum);

void main(){
	int intVal;

	printf("\n Please enter the number whose factorial to be found:");
	scanf("%d", &intVal);
	printf("\n Factorial of a number %d is : %d:", intVal, fnFactorial(intVal));
}
int fnFactorial(int intNum){
	if (intNum < 1)
		return 1;
	else
		return (intNum * fnFactorial(intNum - 1));
}

Ստատիկ գործառույթներ  

Ենթադրենք, որ մենք պետք է գրենք ծրագրի համար ներքին գործառույթներ, և մենք չենք ցանկանում, որ որևէ օգտվողներ օգտագործեն այդ գործառույթը: Այս ներքին գործառույթները կարող են օգտագործվել նույն ծրագրի որոշ այլ գործառույթների կողմից, բայց դրանք չպետք է հասանելի լինեն այլ ծրագրերի, ֆայլերի կամ օգտագործողների համար: Օրինակ, ենթադրենք, որ մենք ունենք մի ծրագիր, որտեղ մենք ստեղծում ենք տարբեր զեկույցներ, ինչպիսիք են ուսանողների գնահատականի հաշվետվությունը, քոլեջի տարեկան հաշվետվությունը և որոշ այլ անձնակազմի հաշվետվություններ: Բայց այս բոլորն ունեն ընդհանուր զեկույցի վերնագիր ՝ քոլեջի անունով, հասցեով, հեռախոսով, ֆաքսով և այլն: Հետևաբար, մենք կարող ենք գործառույթ ունենալ, որպեսզի վերնագրի այս բոլոր տեղեկությունները տպվեն զեկույցում: Բայց վերնագիր ցուցադրելու գործառույթը կկոչվի տարբեր գործառույթներով, որոնք առաջացնում են հաշվետվություններ: Հետևաբար վերնագրի այս գործառույթը ոչ մի կապ չունի օգտագործողների հետ: Նմանապես, ուսանողների հետ կապված այլ ծրագրեր չեն պահանջում վերնագրի այս գործառույթը: Մի խոսքով, մենք չենք ցանկանում, որ որևէ այլ ծրագիր կամ ֆայլ կամ օգտվող օգտագործող մուտք ունենա այս վերնագրի գործառույթը, որը հատուկ ստեղծված է զեկույցի վերնագիր ունենալու համար: Այսպիսով, մենք կարող ենք վերնագրի այս գործառույթը թաքցնել ցանկացած այլ ֆայլերից կամ օգտագործողից և այն օգտագործել այն ֆայլի / ծրագրի կողմից, որում գրված է: Դա արվում է ՝ գործառույթի հայտարարությունից առաջ օգտագործելով «ստատիկ» հիմնաբառ:

Տես նաեւ,
Տվյալների տեսակները C ծրագրավորման մեջ

ստատիկ տվյալների տեսակը function_name (փաստարկ / ներ);
   ստատիկ անվավեր displayHeader ();

Ստատիկ ֆունկցիան այն գործառույթն է, որը կարող է մուտք գործվել այն ֆայլի գործառույթների մեջ, որոնցում ստեղծվել է: Այն հրապարակորեն մատչելի չէ օգտագործողների կամ այլ ծրագրերի համար:

Եկեք ստեղծենք երկու ֆայլ ՝ std_staff_report.c ՝ ուսանողների, աշխատակազմի և տարեկան հաշվետվությունները ցուցադրելու համար, և displayHeader.c ֆայլը ՝ զեկույցի վերնագիրը ցուցադրելու համար: Եկեք stH_staff_report.c ֆայլից զանգահարենք displayHeader () գործառույթը displayHeader ֆայլում ՝ առանց գործառույթը ստատիկ դարձնելու: Այն նորմալ կաշխատի, ինչպես ցանկացած այլ ֆայլ: Եթե ​​մենք ֆունկցիան ստատիկ ենք դարձնում, std_staff_report.c ֆայլից ֆունկցիայի զանգը սխալ է առաջացնում: Եթե ​​մենք այդ գործառույթները stH_staff_report.c- ում գրում ենք displayHeader.c ֆայլի մեջ և զանգահարում ենք դրանք, այն նորմալ կաշխատի: Դա նշանակում է, որ ստատիկ գործառույթները մատչելի են միայն այն գործառույթների համար, որոնք բոլորը նույն ֆայլում են: Ստատիկ գործառույթները մատչելի չեն որևէ այլ օգտագործողի / ֆայլի / ծրագրի, բացի այն գրվածից:

// displayHeader.c
#include <stdio.h>
 static void displayHeader(){
	printf("\nDisplaying Header");
}

 
//std_staff_report.c
#include <stdio.h>
#include "displayHeader.c"// comment this line to see the affect of static
void displayStdReport(char *stdName);
void displayStaffReport(char *staffName);
void displayAnnualReport();

void main(){
	printf("\n\nStudent Report is:");
	displayStdReport("Rose");
	printf("\n\nStaff Report is:");
	displayStaffReport("Robert");
	printf("\n\nAnual Report is:");
	displayAnnualReport();

}
void displayStdReport(char *stdName){
	printf("\nInside %s Student Report Function:", stdName);
	displayHeader();
	printf("\nDisplaying %s Student Report :", stdName);

}
void displayStaffReport(char * staffName){
	printf("\nInside %s Staff Report Function:", staffName);
	displayHeader();
	printf("\nDisplaying %s Staff Report:", staffName);
}
void displayAnnualReport(){
	printf("\nInside Annual Report");
		displayHeader();
		printf("\nDisplaying Annual Report");
}

Ներդրված գործառույթներ  

Ներդրված գործառույթներն այն գործառույթներն են, որոնք ունեն մեկ կամ ավելի գործառույթներ, որոնք կանչվում են դրա մեջ: Օրինակ, հիմնական գործառույթի ներսում ֆունկցիայի զանգը հիմնական գործառույթը դարձնում է որպես տեղադրված գործառույթ: Բնադրվող գործառույթների քանակի սահմանափակում չկա: Մենք արդեն տեսել ենք հիմնական գործառույթների, ռեկուրսիայի ֆունկցիայի, ստատիկ ֆունկցիայի և այլնի գործառույթների բնադրում:

datatype function_name(arguments){
	datatype function_name1(); // declare another function
	…
	datatype function_name1(); // call the function
	….
	datatype function_name1(){ //define the function
	…
	}
}

Հիմնական ֆունկցիայի շրջանակներում կատարված տարբեր թվաբանական գործողությունները բնադրված զվարճանքի օրինակ են:
#include <stdio.h>

//Function Declaration
void add(int intNum1, int intNum2);
void minus(int intNum1, int intNum2);
void divide(int intNum1, int intNum2);
void multiply(int intNum1, int intNum2);

void main(){
	// calling different functions within another function
	add(30, 60);
	minus(100, 23);
	divide(25, 5);
	multiply(400, 7);
	printf("\n End of the arithmetic Operation….");
}

void add (int intNum1, int intNum2){
	printf("\nSum of %d and %d is : %d", intNum1, intNum2, intNum1 + intNum2);
}
void minus(int intNum1, int intNum2){
	printf("\nDifference of %d and %d is : %d", intNum1, intNum2, intNum1 - intNum2);
}
void divide(int intNum1, int intNum2){
	printf("\nResult of %d / %d is : %d", intNum1, intNum2, intNum1 / intNum2);
}
void multiply(int intNum1, int intNum2){
	printf("\nResult of %d * %d is : %d", intNum1, intNum2, intNum1*intNum2);
}

Ամփոփում  

  • Ֆունկցիան ծրագրում ծածկագրված անվանումով բազմակի օգտագործման կոդ է:
  • Գոյություն ունեն երկու տեսակի գործառույթներ ՝ Գրադարանի գործառույթներ և Օգտագործողի կողմից սահմանված գործառույթներ:
  • Գրադարանի գործառույթներն են `հիմնական (), scanf, ստացումներ, getchar, printf, put, putchar, malloc, calloc, sqrt, sin, cos, tan, հարկ, exp, tolower, touch, isdigit, isalpha և այլն:
  • Ֆունկցիայի պարամետրերը կարող են փոխանցվել երկու եղանակով `անցնել արժեքով և անցնել հղումով:
  • Անցումային արժեքով փոխանցվում է փաստացի պարամետրի արժեքը, և ֆունկցիան չի կարող փոխել իրական պարամետրի արժեքը
  • Հղումով փոխանցման ժամանակ փոխանցվում է փաստացի պարամետրի հասցեն, և պաշտոնական պարամետրի արժեքի ցանկացած փոփոխություն կփոխի նաև իրական պարամետրերի արժեքը: Բայց երկուսն էլ պարամետրի հասցեն մնում է նույնը:
  • Variadic գործառույթներն այն գործառույթներն են, որոնք ընդունում են ցանկացած տիպի պարամետրի փոփոխական քանակ:
  • Ստատիկ գործառույթները ֆունկցիաներ են, որոնք տեսանելի չեն ֆայլերի կամ ծրագրերի կամ օգտագործողների համար, բացի այն ֆայլից, որտեղ այն գրվել է:
  • Ներդրված գործառույթները այլ գործառույթների շրջանակներում սահմանված գործառույթներն են:
  • Ռեկուրսիվ ֆունկցիան այն գործառույթն է, որի ընթացքում նույն գործառույթները բազմիցս կանչվում են դրա շրջանակներում: