510 likes | 700 Views
Úvod do jazyka C. Algoritmizácia úloh. Smerníky. Smerník – pointer je premenná, ktorá obsahuje adresu inej premennej. Príklady definícii: int *cislo; -smerník na int (celé) číslo float *cislo; -smerník na float (reálne) číslo double *cislo; -smerník na double číslo. Smerníky.
E N D
Úvod do jazyka C Algoritmizácia úloh
Smerníky Smerník – pointer je premenná, ktorá obsahuje adresu inej premennej. Príklady definícii: int *cislo; -smerník na int (celé) číslo float *cislo; -smerník na float (reálne) číslo double *cislo; -smerník na double číslo
Smerníky 1000 1003 ............... 12 55 47 int a; int *pa; pa = &a; pa
Operátory & referenčný operátor Výraz &a predstavuje adresu premennej a v pamäti * dereferenčný operátor *p je obsah adresy na ktorú ukazuje smerník p.
Deklarácia premennej typu smerník int x=15, *p; /* inicializácia premennej a deklarácia smerníka */ p = &x; /* smerník 'p' bude obsahovať adresu premennej ‚x' */ *p = 3; /* hodnota 3 sa uloží do premennej, na ktorú ukazuje 'p' */
Príklad 1: Bez použitia premennej x priamo pri výpočte zvýšte jej hodnotu o 10. smerník na int alebo smerník typu int int x = 0; int*smernik; smernik = &x; printf("\n hodnota x pred zmenou: %d",x); *smernik = 0; *smernik = *smernik + 10; printf("\n po pripocitani: x = %d \n",x); return 0; • do smerníka sme uložili adresu x Do obsah adresy kde je x ,sme pripočítali 10
Príklad int main(int argc, char *argv[]) { int x = 15 ; //do x sme vložili hodnotu 15 int *smernik; //deklarácia smernik typu int smernik = &x; // do smerníka sme uložili adresu x printf("\nAdresa kde ukazuje smernik je : %d",smernik); printf("\nAdresa premennej x je : %d",&x); printf("\nHodnota,kde ukazuje smernik: %d",*smernik); printf("\nHodnota premennej x je : %d",x ); system("PAUSE"); return 0; }
smernik = &x;Vďaka znaku & získame adresu premennej x. smerník = x - Nesprávne!!!, do smerníka by sme si uložili namiesto adresy hodnotu premennej. V našom prípade by to bola 0. Takže smerník by nám ukazoval na adresu 0 a nie na adresu, kde je uložená hodnota premennej x. Znak & - referenčný operátor.
*smernik = *smernik + 10;Vďaka znaku * získame obsah na adrese, na ktorú ukazuje. Znak * dereferenčný operátor. Vyššie uvedená verzia je totožná s: x = x + 10;
Príklad chybných príkazov: smernik = &10 ; - chyba 10 je konštanta => nemá adresu smernik = &(x + 10) ; - chyba (x+10) je výraz smernik = 1 ; - smerník by teraz ukazoval niekam na adresu 1
Použitie smerníkov int x = 15 ; int* smernik; smernik = &x; - do smerníka sme uložili adresu x printf("\nAdresa kde ukazuje smernik je : %d",smernik); printf("\nAdresa premennej x je : %d",&x); printf("\nHodnota,kde ukazuje smernik je %d “, *smernik); printf("\nHodnota premennej x je : %d",x ); printf("\n\n\n"); smernik++; x++; printf("\nAdresa kde ukazuje smernik je : %d",smernik); printf("\nAdresa premennej x je : %d\n",&(x)); printf("\nHodnota,kde ukazuje smernik je %d: “, *smernik); printf("\nHodnota premennej x je : %d\n",x );
Použitie smerníkov Priradenie hodnoty z pamäti, ktorá je na adrese, na ktorú ukazuje smerník p_i premennej i i = *p_i;
adresa Použitie pointerov Priradenie adresy premennej i pointeru p_i = &i; *p_i=71
Príklad práce s pointrami int main() { int i = 5, j=6; *p; printf(“\n\r Pred: i=%d j=%d ”, i, j); p = &i; j = *p; printf(“\n\r Po: i=%d j=%d ”, i, j); }
Priradenie Staticky správne: i = 3, j=10, *p_i; p_i = &i; // priradenia hodnôt *p_i = 4; *p_i = j; j=*p_i;
Priradenie - chyby Staticky nesprávne: p_i = 3; do p_i je vložená adresa 3 i = p_i; do i sa dá obsah p_i tzn. adresa namiesto hodnoty i = &p_i; do i sa dá adresa p_i
Príklad Načítať dve celé čísla z klávesnice a vypísať to číslo, ktoré bude väčšie #include <stdio.h> int main() { int i, j, *p_i; scanf("%d %d",&i, &j); p_i = (i > j) ? &i : &j; printf("Vacsie je cislo %d\n", *p_i); }
Veľkosť vyhradeného pamäťového priestoru Veľkosť pamäti vyhradenej pre dáta v spolupráci s pointrami je možné určiť príkazom sizeof Príklad: int main() { int i, j; double *p_i; i = sizeof(p_i); j = sizeof(*p_i); printf("Velkost pam. priestoru pre p_i: %d\n", i); printf("Velkost pam. priestoru pre *p_i: %d", j);}
Platné operácie s pointrami S pointrami je možné vykonávať nasledujúce operácie: • súčet pointra a celého čísla, • rozdiel pointra a celého čísla, • porovnanie pointrov rovnakých typov, • rozdiel dvoch pointrov rovnakých typov.
Pointre a funkcie – volanie odkazom Pointre umožňujú odovzdanie parametrov odkazom. To umožňuje vo funkcii trvalo zmeniť hodnotu skutočného parametra.
Pointre a funkcie – volanie odkazom To dosiahneme, keď neodovzdávame hodnotu premennej, ale adresu tejto premennej. V zásobníku sa vytvorí lokálna premenná, v ktorej je uložená adresa skutočného parametra. Táto premenná po skončení funkcie zaniká, ale prostredníctvom pointra, ktorý v nej bol uložený sa mení skutočná premenná, ktorá je mimo funkcie. Vo funkcii ale musíme pracovať s pointrom. Ide o nepriame volanie odkazom.
Zadanie • Vytvorte funkciu, ktorá vymení 2 čísla
#include <stdio.h> #include "moje.h" void vymen(int x, int y) { int pom; pom = x; x = y; y = pom; } int main() { int i = 21, j = 12; printf(" Hodnota i je: %d\n", i); printf(" Hodnota j je: %d\n", j); vymen(i, j); printf(" Hodnota i je: %d\n", i); printf(" Hodnota j je: %d\n", j); } Použitie funkcie, ktorá zabezpečí zámenu dvoch premenných Táto verzia fungovať nebude, lebo do funkcie vymen() sú vložené len hodnoty
#include <stdio.h> #include "moje.h" void vymen(int *p_x, int *p_y) { int pom; pom = *p_x; *p_x = *p_y; *p_y = pom; } int main() { int i = 21, j = 12; printf(" Hodnota i je: %d\n", i); printf(" Hodnota j je: %d\n", j); vymen(&i, &j); printf(" Hodnota i je: %d\n", i); printf(" Hodnota j je: %d\n", j); } Použitie funkcie, ktorá zabezpečí zámenu dvoch premenných 43
Zadanie • Vytvorte funkciu, ktorá vypíše znaky reťazca • Použite FOR
Práca s reťazcami #include <stdio.h> #include <string.h> void fcia(char *str) { int i; for(i=0; i<(strlen(str)+1); i++) { printf("\n\r Znak %d je %c ", i, *(str+i) ); } return; } main() { char text1[]="Nejaky text"; fcia((char*)&text1); while(1); }
Zadanie • Vytvorte funkciu, ktorá vypíše znaky reťazca • Použite WHILE a inkrementáciu ukazovateľa
Práca s reťazcami #include <stdio.h> #include <string.h> void fcia(char *str) { int i; while(*str!=0) { printf("\n\r Znak %d je %c (str=%d)", i, *str, str ); str++; i++; } return; } main() { char text1[]="Nejaky text"; fcia((char*)&text1); while(1); }
Zadanie • Vytvorte funkciu, ktorá na ukázanú adresu prekopíruje nejaký reťazec
Práca s reťazcami #include <stdio.h> #include <string.h> void fcia(char *str) { int i=0; strcpy(str,"Iny text"); return; } main() { char text1[50]="Text1111111"; printf("\n\r Pred: '%s' ", text1); fcia((char*)&text1); printf("\n\r Pod: '%s' ", text1); while(1); }
Dynamické prideľovanie pamäti Na prideľovanie pamäte sa používa funkcia malloc() Ako argument prijíma veľkosť pamäte, ktorá sa má alokovať. Napr. char *p_str; int *p_int; p_str = (char*) malloc( sizeof(char) * 1000); p_int = (int*) malloc( sizeof(int) * 1000);
Uvoľnenie pamäti Pre uvoľnenie pamäti sa používa príkaz free() int *p_i; p_i = (int *) malloc(1000); free(p_i);
Príklad – kostra programu #include <stdio.h> #include <stdlib.h> #include <string.h> int SIZE=20; main() { int i,*p_a; p_a=(int*) malloc(sizeof(int) * SIZE); if(p_a==NULL) { printf("\n\r CHYBA: Malo pamate"); return 1; } // ........ nejake operacie; free(p_a); }
Zadanie • Dynamicky alokujte miesto pre 20 čísel (pole) • Naplňte toto pole náhodnými hodnotami • Vypíšte toto pole vo funkcii a následne aj priamo v main()
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int SIZE=20; void generuj_cisla(int *cisla) { int i; for(i=0; i<SIZE; i++) *(cisla+i)=rand()%10; for(i=0; i<SIZE; i++) printf("\n\r generuj_cisla(): Prvok %d je %d ", i, *(cisla+i)); } main() { int i,*p_a; srand(time(NULL)); p_a=(int*)malloc(sizeof(int)*SIZE); generuj_cisla(p_a); for(i=0; i<SIZE; i++) printf("\n\r main(): Prvok %d je %d ", i, *(p_a+i)); free(p_a); while(1); }
Zadanie • Naplňte pole hodnotami, pričom každá hodnota sa bude vypočítavať ako i*2
Normálne naplnenie poľa a jeho výpis #include <stdio.h> main() { int i, a[5]; for(i=0; i<5; i++) { a[i]=i*2; } for(i=0; i<5; i++) { printf("\n\r a[%d] = %d ",i,a[i]); } return 0; }
Zadanie • Naplňte pole hodnotami, pričom každá hodnota sa bude vypočítavať ako i*2 • Použite smerníky
Naplnenie poľa a jeho výpis pomocou smerníkov #include <stdio.h> main() { int i, a[5]; ptr=(int*)&a; for(i=0; i<5; i++) { a[i] = i*2; } for(i=0; i<5; i++) { printf("\n\r"); printf("\n\r %d. smernik ptr ukazuje na adresu 0x%x, ", i, (ptr+i)); printf("\n\r %d. je tam hodnota %d ", i, *(ptr+i)); //ptr++; } return 0; }
Zadanie • Naplňte maticu 3x3 hodnotami, pričom každá hodnota sa bude načítať z klávesnice
Matica – načítanie #include<stdio.h> int main(void){ int i,j; int pole[3][3]; for(i = 0;i<3;i++) // indexácia od 0 !!! { printf(“\n Zadajte 3 cisla do %d.riadku",i+1); for(j = 0;j<3;j++) // indexácia od 0!!! { printf("nZadajde %d.cislo.",j+1); scanf("%d",&pole[i][j]); }}; >>>>> tu program pokračuje 61
Matica – výpis printf("Vytvorena matica "); for(i = 0;i<3;i++) { for(j = 0;j<3;j++) { printf("%d ",pole[i][j]); //jednoduchý výpis }; printf("n"); }; 62
Zadanie • Naplňte maticu 3x3 hodnotami, pričom každá hodnota sa bude načítať z klávesnice • Použite smerníky
Matica – načítanie(použitie smerníkov) #include<stdio.h> int main(void){ int i,j; int pole[3][3]; for(i = 0;i<3;i++) { printf(“\n Zadajte 3 cisla do %d.riadku",i+1); for(j = 0;j<3;j++) { printf("nZadajte %d.cislo.",j+1); scanf("%d",(pole[i] + j) ); } }; 64
Matica – výpis(použitie smerníkov) printf(“\nVytvorena matica pole"); for(i = 0;i<3;i++) { for(j = 0;j<3;j++) { printf("%d ",*(pole[i] + j)); }; printf("n"); }; 65
&pole[j][i] = pole[j] + i = *(pole + j) + ipole[j][i] = *(pole[j] + i) = *((*(pole+j))+i)Meno poľa je symbolická konštanta, ktorej hodnota je smerník na umiestnenie prvého prvku poľa. Preto pre názov poľa môžeme využiť „kúzla“ so smerníkmi. Chcem zvýrazniť, že je to konštanta a tak sa k nej treba aj správať! 66