Práce s ukazateli
Napište program, který ve funkci zamění obsah dvou polí záměnou ukazatelů na tato pole. Použijte vzor programu (připravený k doplnění) uvedený níže v tomto textu.
Zkuste nejprve příponu „c“. Po odladění zkuste přeložit s příponou cpp a odstraňte chyby plynoucí z přísnějšího přístupu ke konverzi ukazatelů.
Pozn.:
Na začátku programu předpokládáme naalokování dvou polí (p_x a p_y jsou ukazatele na int, tj. Adresy počátku pole intů, které dá malloc. V případě použití *p_x se přistupuje na hodnotu uloženou na adrese p_x, tj. K prvnímu prvku pole. Adresa, na které leží proměnná p_x se získá pomocí &p_x.)
int * pole intů
p_x -> int 10, int11, int12, int13 (p_x ukazuje na pole proměnných typu int)
p_y -> int 20, int 21, int 22, int 23
Naším úkolem je, aby (výměnou hodnot pole1 a pole2 ve funkci) došlo k následujícímu
int * pole intů
p_x -> int 20, int 21, int 22, int 23
p_y -> int 10, int11, int12, int13
Předáme-li do funkce hodnotu pole1 a pole2, budou ve funkci pouze lokální kopie (ukazatelů na počátek pole) a jejich výměna se neprojeví vně.
Proto je nutné do funkce dát adresu, na které leží proměnné (p_x, p_y), jejichž obsah chceme měnit. Výměnou obsahu (adres polí) vlastně vyměníme pole.
Typ void ve funkci používáme proto, že není důležité (z hlediska algoritmu) na co je ukazatel (typ pole), protože se mění pouze ukazatele ( a ty jsou pro všechny typy stejné). Funkce je tedy použitelná pro pole libovolného typu. (void se tedy dá chápat nejen jako ukazatel na „nic“ ale také jako ukazatel na „cokoli“ neboli univerzální ukazatel)
Sled proměnných a jejich obsahů je tedy ve funkci tento:
void ** (int **) |
void* (int *) |
(int) |
p1 (&p_x) |
*p1 (p_x) |
(p_x[ i ]) |
adresa na níž je měněná proměnná |
Obsah měněné proměnné (adresa počátku pole) |
(prvky) pole |
=================== vzor ====================
// Tento program vytvori dve pole v dynamicke pameti // Vytvori na ne ukazatele a ty pomoci externi funkce exchange // prehodi. #include <conio.h> #include <stdio.h> #include <malloc.h> void exchange (void **p1,void **p2) { } int main (void) { // clrscr(); int *p_x,*p_y; p_x=malloc(sizeof(int)*50); p_y=malloc(sizeof(int)*50); printf("Alokovano......\n"); printf(" px= %p , py= %p\n",p_x,p_y); printf("Prehazuju......\n"); // exchange (); // Semhle prijde napsat volani funkce Exchange se vstupnimi parametry. printf(" px= %p , py= %p\n",p_x,p_y); free (p_x); free (p_y); printf("Dealokovano......\n"); printf(" px= %p , py= %p\n",p_x,p_y); printf("Konec.\n"); return 0; }
================ konec vzoru ==================
V případě ukazatelů (či jiného programování) je výhodné „čmárat“. Získáte tak lepší představu o dané situaci
Obrázek znázorňuje ve střední části místa v paměti a jejich názvy (i, pi …). Vpravo jsou příslušné definice proměnných, které zajišťují názvy pro proměnné a příslušné místo v paměti, společné s inicializací. V levé části jsou odpovídající zápisy pro přístup k daným proměnným podle definicí z pravé části.
V místě mezi P2 a P_Y (a P1 a P_X) je hranice mezi volající a volanou funkcí
Poslední změna 2007-08-31