Rādītāji sniedz lielas iespējas “C” funkcijām, kuras mums ir ierobežotas, lai atgrieztu vienu vērtību. Izmantojot rādītāja parametrus, mūsu funkcijas tagad var apstrādāt faktiskos datus, nevis datu kopiju.
Lai mainītu mainīgo faktiskās vērtības, izsaukuma priekšraksts adresē funkcijas nosūta adreses rādītāja parametriem.
Šajā apmācībā jūs uzzināsiet
- Funkciju rādītāju piemērs
- Funkcijas ar masīva parametriem
- Funkcijas, kas atgriež masīvu
- Funkciju rādītāji
- Funkciju norāžu masīvs
- Funkcijas, izmantojot tukšās norādes
- Funkciju rādītāji kā argumenti
Funkciju rādītāju piemērs
Piemēram, nākamā programma apmaina divas divu vērtības:
void swap (int *a, int *b);int main() {int m = 25;int n = 100;printf("m is %d, n is %d\n", m, n);swap(&m, &n);printf("m is %d, n is %d\n", m, n);return 0;}void swap (int *a, int *b) {int temp;temp = *a;*a = *b;*b = temp;}}
Izeja:
m is 25, n is 100m is 100, n is 25
Programma maina faktisko mainīgo vērtības, jo funkcija tām piekļūst, izmantojot adresi, izmantojot rādītājus. Šeit mēs apspriedīsim programmas procesu:
- Mēs pasludinām funkciju, kas ir atbildīga par divu mainīgo vērtību nomaiņu, kas kā parametrus ņem divus veselā skaitļa rādītājus un atgriež jebkuru vērtību, kad to izsauc.
- Galvenajā funkcijā mēs deklarējam un inicializējam divus veselu skaitļu mainīgos ('m' un 'n'), pēc tam attiecīgi izdrukājam to vērtības.
- Mēs saucam funkciju swap (), nododot divu mainīgo adresi kā argumentus, izmantojot simbolu ampersand. Pēc tam mēs izdrukājam jaunās mainīgās mainīgo vērtības.
- Šeit mēs definējam swap () funkcijas saturu, kurā par parametriem tiek ņemtas divas veselu skaitļu mainīgo adreses, un deklarējam pagaidu vesela skaitļa mainīgo, ko izmanto kā trešo krātuves lodziņu, lai saglabātu vienu no vērtības mainīgajiem, kas tiks ievietots otrajā mainīgajā.
- Saglabājiet pirmā mainīgā saturu, uz kuru pagaidu mainīgajā norāda “a”.
- Glabājiet otro mainīgo, kuru norāda b, pirmajā mainīgajā, kuru norāda a.
- Atjauniniet otro mainīgo (norāda b) ar pirmā mainīgā vērtību, kas saglabāta pagaidu mainīgajā.
Funkcijas ar masīva parametriem
C, mēs nevaram nodot masīvu pēc vērtības funkcijai. Tā kā masīva nosaukums ir rādītājs (adrese), tāpēc mēs vienkārši nododam masīva nosaukumu funkcijai, kas nozīmē nodot rādītāju masīvam.
Piemēram, mēs uzskatām šādu programmu:
int add_array (int *a, int num_elements);int main() {int Tab[5] = {100, 220, 37, 16, 98};printf("Total summation is %d\n", add_array(Tab, 5));return 0;}int add_array (int *p, int size) {int total = 0;int k;for (k = 0; k < size; k++) {total += p[k]; /* it is equivalent to total +=*p ;p++; */}return (total);}
Izeja:
Total summation is 471
Šeit mēs izskaidrosim programmas kodu ar tā detaļām
- Mēs deklarējam un definējam funkciju add_array (), kas kā parametrus ņem masīva adresi (rādītāju) ar elementu numuru un atgriež šo elementu kopējo summēto summu. Rādītājs tiek izmantots, lai atkārtotu masīva elementus (izmantojot p [k] apzīmējumu), un mēs apkopojam summēšanu vietējā mainīgajā, kas tiks atgriezts pēc visa elementa masīva atkārtojuma.
- Mēs deklarējam un inicializējam vesela skaitļa masīvu ar pieciem veselu skaitļu elementiem. Kopējo summēšanu mēs izdrukājam, nododot masīva nosaukumu (kas darbojas kā adrese) un masīva izmēru funkcijai add_array (), ko sauc par argumentiem.
Funkcijas, kas atgriež masīvu
C, mēs varam atgriezt rādītāju masīvā, kā šajā programmā:
#includeint * build_array();int main() {int *a;a = build_array(); /* get first 5 even numbers */for (k = 0; k < 5; k++)printf("%d\n", a[k]);return 0;}int * build_array() {static int Tab[5]={1,2,3,4,5};return (Tab);}
Izeja:
12345
Un šeit mēs apspriedīsim programmas detaļas
- Mēs definējam un deklarējam funkciju, kas atgriež masīva adresi, kurā ir vesels skaitlis, un neieņēma nevienu argumentu.
- Mēs deklarējam veselu skaitli, kas saņem pilnu masīvu, kas izveidots pēc funkcijas izsaukšanas, un mēs drukājam tā saturu, atkārtojot visu piecu elementu masīvu.
Ievērojiet, ka funkcijas masīva adreses glabāšanai ir definēts rādītājs, nevis masīvs. Ievērojiet arī to, ka tad, kad vietējais mainīgais tiek atgriezts no funkcijas, mums tas ir jādeklarē kā statisks.
Funkciju rādītāji
Kā mēs pēc definīcijas zinām, ka rādītāji norāda uz adresi jebkurā atmiņas vietā, tie var arī norādīt izpildāmā koda sākumā kā funkcijas atmiņā.
Rādītājs darbībai tiek deklarēts ar *, tā deklarācijas vispārīgais paziņojums ir:
return_type (*function_name)(arguments)
Jums jāatceras, ka iekavas ap (* function_name) ir svarīgas, jo bez tām sastādītājs domās, ka function_name atgriež rādītāju return_type.
Pēc funkcijas rādītāja noteikšanas mums tas jāpiešķir funkcijai. Piemēram, nākamā programma deklarē parasto funkciju, nosaka funkcijas rādītāju, piešķir funkcijas rādītāju parastajai funkcijai un pēc tam izsauc funkciju caur rādītāju:
#includevoid Hi_function (int times); /* function */int main() {void (*function_ptr)(int); /* function pointer Declaration */function_ptr = Hi_function; /* pointer assignment */function_ptr (3); /* function call */return 0;}void Hi_function (int times) {int k;for (k = 0; k < times; k++) printf("Hi\n");}
Izeja:
HiHiHi
- Mēs definējam un deklarējam standarta funkciju, kas izdrukā Hi tekstu k reizes, ko norāda parametru reizes, kad funkcija tiek izsaukta
- Mēs definējam rādītāja funkciju (ar tās īpašo deklarāciju), kas ņem vesela skaitļa parametru un neko neatgriež.
- Mēs inicializējam rādītāja funkciju ar Hi_function, kas nozīmē, ka rādītājs norāda uz Hi_function ().
- Tā vietā, lai izsauktu standarta funkciju, pieskaroties funkcijas nosaukumam ar argumentiem, mēs saucam tikai rādītāja funkciju, argumentiem nododot skaitli 3, un viss!
Paturiet prātā, ka funkcijas nosaukums norāda uz izpildāmā koda sākuma adresi kā masīva nosaukums, kas norāda uz tā pirmo elementu. Tādēļ tādas instrukcijas kā function_ptr = & Hi_function un (* funptr) (3) ir pareizas.
PIEZĪME. Funkciju piešķiršanas un izsaukuma laikā nav svarīgi ievietot adreses operatoru un un netiešo operatoru *.
Funkciju norāžu masīvs
Funkciju norāžu masīvs var spēlēt slēdzi vai if paziņojuma lomu lēmuma pieņemšanai, tāpat kā nākamajā programmā:
#includeint sum(int num1, int num2);int sub(int num1, int num2);int mult(int num1, int num2);int div(int num1, int num2);int main(){ int x, y, choice, result;int (*ope[4])(int, int);ope[0] = sum;ope[1] = sub;ope[2] = mult;ope[3] = div;printf("Enter two integer numbers: ");scanf("%d%d", &x, &y);printf("Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: ");scanf("%d", &choice);result = ope[choice](x, y);printf("%d", result);return 0;}int sum(int x, int y) {return(x + y);}int sub(int x, int y) {return(x - y);}int mult(int x, int y) {return(x * y);}int div(int x, int y) {if (y != 0) return (x / y); else return 0;}
Enter two integer numbers: 13 48Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: 2624
Šeit mēs apspriežam programmas informāciju:
- Mēs deklarējam un definējam četras funkcijas, kas ņem divus veselā skaitļa argumentus un atgriež vesela skaitļa vērtību. Šīs funkcijas saskaita, atņem, reizina un sadala divus argumentus attiecībā uz to, kuru funkciju lietotājs izsauc.
- Mēs deklarējam 4 veselus skaitļus, lai attiecīgi apstrādātu operandus, operācijas veidu un rezultātu. Mēs arī deklarējam četru funkciju rādītāja masīvu. Katrs masīva elementa funkcijas rādītājs ņem divus veselu skaitļu parametrus un atgriež vesela skaitļa vērtību.
- Mēs piešķiram un inicializējam katru masīva elementu ar jau deklarēto funkciju. Piemēram, trešais elements, kas ir trešais funkcijas rādītājs, norādīs uz reizināšanas darbības funkciju.
- Mēs meklējam operandus un darbības veidu no lietotāja, kas ierakstīts ar tastatūru.
- Mēs izsaucām atbilstošo masīva elementu (Funkcijas rādītājs) ar argumentiem, un mēs saglabājam atbilstošās funkcijas radīto rezultātu.
Instrukcija int (* ope [4]) (int, int); nosaka funkciju rādītāju masīvu. Katram masīva elementam jābūt vienādiem parametriem un atgriešanās tipam.
Izteikuma rezultāts = ope [izvēle] (x, y); palaiž atbilstošo funkciju atbilstoši lietotāja izdarītajai izvēlei. Divi ievadītie veseli skaitļi ir funkcijai nodotie argumenti.
Funkcijas, izmantojot tukšās norādes
Vold pointers tiek izmantots funkciju deklarāciju laikā. Mēs izmantojam anulēšanas * atgriešanas tipa atļaujas jebkura veida atgriešanai. Ja mēs pieņemam, ka mūsu parametri nemainās, pārejot uz funkciju, mēs to pasludinām par const.
Piemēram:
void * cube (const void *);
Apsveriet šādu programmu:
#includevoid* cube (const void* num);int main() {int x, cube_int;x = 4;cube_int = cube (&x);printf("%d cubed is %d\n", x, cube_int);return 0;}void* cube (const void *num) {int result;result = (*(int *)num) * (*(int *)num) * (*(int *)num);return result;}
Rezultāts:
4 cubed is 64
Šeit mēs apspriedīsim programmas informāciju:
- Mēs definējam un deklarējam funkciju, kas atgriež veselu skaitli un iegūst nemainīga mainīgā adresi bez konkrēta datu veida. Mēs aprēķinām satura mainīgā (x) kuba vērtību, uz kuru norāda ciparu rādītājs, un, tā kā tas ir tukšs rādītājs, mums tas ir jāieraksta ar skaitļa datu tipu, izmantojot noteiktu apzīmējuma (* datatipa) rādītāju, un mēs atgriezīsimies kuba vērtība.
- Mēs deklarējam operandu un rezultāta mainīgo. Mēs arī inicializējam savu operandu ar vērtību "4."
- Mēs izsaucam kuba funkciju, nododot operanda adresi, un mēs apstrādājam atgriežamo vērtību rezultāta mainīgajā
Funkciju rādītāji kā argumenti
Vēl viens veids, kā izmantot funkciju rādītāju, nododot to kā argumentu citai funkcijai, ko dažreiz sauc par "atzvanīšanas funkciju", jo saņēmēja funkcija "to izsauc".
Stdlib.h galvenes failā funkcija Quicksort "qsort ()" izmanto šo tehniku, kas ir algoritms, kas paredzēts masīva kārtošanai.
void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
- void * base: nederīgs masīva rādītājs.
- size_t num: masīva elementa numurs.
- size_t width Elementa lielums.
- int (* salīdzināt (const void *, const void *): funkcijas rādītājs, kas sastāv no diviem argumentiem un atgriež 0, ja argumentiem ir vienāda vērtība, <0, ja arg1 nāk pirms arg2, un> 0, ja arg1 nāk pēc arg2.
Izmantojot qsort (), šī programma sakārto veselu skaitļu masīvu no maza līdz lielam skaitlim:
#include#include int compare (const void *, const void *);int main() {int arr[5] = {52, 14, 50, 48, 13};int num, width, i;num = sizeof(arr)/sizeof(arr[0]);width = sizeof(arr[0]);qsort((void *)arr, num, width, compare);for (i = 0; i < 5; i++)printf("%d ", arr[ i ]);return 0;}int compare (const void *elem1, const void *elem2) {if ((*(int *)elem1) == (*(int *)elem2)) return 0;else if ((*(int *)elem1) < (*(int *)elem2)) return -1;else return 1;}
Rezultāts:
13 14 48 50 52
Šeit mēs apspriedīsim programmas informāciju:
- Mēs definējam salīdzināšanas funkciju, kas sastāv no diviem argumentiem, un atgriež 0, ja argumentiem ir vienāda vērtība, <0, kad arg1 nāk pirms arg2, un> 0, kad arg1 nāk pēc arg2. Parametri ir tukšu rādītāju tips, kas nodots attiecīgajam masīva datu tipam (vesels skaitlis)
- Mēs noteikt un inicializēt veselu masīvu masīva izmērs tiek glabāta num mainīgo un lielumu, katra masīva elementa tiek glabāta platuma mainīgo izmantojot sizeof () iepriekšnoteikta C operatoru.
- Mēs izsaucam qsort funkciju un nododam masīva nosaukumu, izmēru, platumu un salīdzināšanas funkciju, ko iepriekš definējis lietotājs, lai kārtotu mūsu masīvu augošā secībā. Salīdzinājums tiks veikts, katrā atkārtojumā ņemot divus masīva elementus līdz visam masīvam tiks sakārtoti.
- Mēs drukājam masīva elementus, lai pārliecinātos, ka mūsu masīvs ir labi sakārtots, atkārtojot visu masīvu, izmantojot cilpu.