Ukazatele v C: Co je Ukazatel v programování C? Typy
Co je ukazatel v C?
Jedno ukazatel v C je proměnná, která ukládá adresu jiné proměnné. Ukazatel lze také použít k odkazování na jinou funkci ukazatele. Ukazatel lze zvyšovat/snižovat, tj. ukazovat na další/předchozí paměťové místo. Účelem ukazatele je ušetřit místo v paměti a dosáhnout rychlejší doby provádění.
Jak používat ukazatele v C
Pokud deklarujeme proměnnou v typu int, v bude ve skutečnosti ukládat hodnotu.
v se nyní rovná nule.
Každá proměnná má však kromě hodnoty i svou adresu (nebo zjednodušeně řečeno, kde se v paměti nachází). Adresu lze získat vložením ampersandu (&) před název proměnné.
Pokud vytisknete adresu proměnné na obrazovku, bude to vypadat jako zcela náhodné číslo (navíc se může lišit běh od běhu).
Zkusme to v praxi s ukazatelem v C příkladu
Výstup tohoto programu je -480613588.
Co je ukazatel? Místo uložení hodnoty bude ukazatel y ukládat adresu proměnné.
Proměnná ukazatele
Int *y = &v;
VARIABILNÍ | UKAZATEL |
---|---|
A hodnota uložené v pojmenovaný adresa úložiště/paměti | A proměnlivý že poukazuje na adresu úložiště/paměti další proměnlivý |
Vyhlášení ukazatele
Stejně jako proměnné, ukazatele in C programování musí být deklarovány, než je lze použít ve vašem programu. Ukazatele lze pojmenovat jakkoli chcete, pokud splňují pravidla pro pojmenování C. Deklarace ukazatele má následující tvar.
data_type * pointer_variable_name;
Zde,
- datový typ je základní typ ukazatele z typů proměnných C a označuje typ proměnné, na kterou ukazatel ukazuje.
- Hvězdička (*: stejná hvězdička používaná pro násobení), což je nepřímý operátor, deklaruje ukazatel.
Podívejme se na některé platné deklarace ukazatelů v tomto tutoriálu o ukazatelích C:
int *ptr_thing; /* pointer to an integer */ int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */ double *ptr2; /* pointer to a double */ float *ptr3; /* pointer to a float */ char *ch1 ; /* pointer to a character */ float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */
Inicializujte ukazatel
Po deklaraci ukazatele jej inicializujeme jako standardní proměnné s proměnnou adresou. Pokud jsou ukazatele v programování v jazyce C neinicializované a používané v programu, výsledky mohou být nepředvídatelné a potenciálně katastrofální.
K získání adresy proměnné používáme operátor ampersand (&), umístěný před názvem proměnné, jejíž adresu potřebujeme. Inicializace ukazatele se provádí s následující syntaxí.
Syntaxe ukazatele
pointer = &variable;
Jednoduchý program pro ilustraci ukazatele je uveden níže:
#include <stdio.h> int main() { int a=10; //variable declaration int *p; //pointer variable declaration p=&a; //store address of variable a in pointer p printf("Address stored in a variable p is:%x\n",p); //accessing the address printf("Value stored in a variable p is:%d\n",*p); //accessing the value return 0; }
Výstup:
Address stored in a variable p is:60ff08 Value stored in a variable p is:10
OperaTor | Význam |
---|---|
* | Slouží ke 2 účelům
|
& | Slouží pouze k 1 účelu
|
Typy ukazatelů v C
Následující jsou různé Typy ukazatelů v C:
Nulová ukazatel
Můžeme vytvořit nulový ukazatel přiřazením nulové hodnoty během deklarace ukazatele. Tato metoda je užitečná, když nemáte přiřazenou žádnou adresu k ukazateli. Nulový ukazatel vždy obsahuje hodnotu 0.
Následující program ilustruje použití nulového ukazatele:
#include <stdio.h> int main() { int *p = NULL; //null pointer printf(“The value inside variable p is:\n%x”,p); return 0; }
Výstup:
The value inside variable p is: 0
Void Ukazatel
In C programování, ukazatel void se také nazývá obecný ukazatel. Nemá žádný standardní datový typ. Ukazatel void se vytvoří pomocí klíčového slova void. Lze jej použít k uložení adresy libovolné proměnné.
Následující program ilustruje použití ukazatele void:
#include <stdio.h> int main() { void *p = NULL; //void pointer printf("The size of pointer is:%d\n",sizeof(p)); return 0; }
Výstup:
The size of pointer is:4
Divoký ukazatel
Ukazatel se nazývá divoký ukazatel, pokud není na nic inicializován. Tyto typy C ukazatelů nejsou efektivní, protože mohou ukazovat na nějaké neznámé místo v paměti, což může způsobit problémy v našem programu a může to vést k pádu programu. Člověk by měl být vždy opatrný při práci s divokými ukazateli.
Následující program ilustruje použití divokého ukazatele:
#include <stdio.h> int main() { int *p; //wild pointer printf("\n%d",*p); return 0; }
Výstup:
timeout: the monitored command dumped core sh: line 1: 95298 Segmentation fault timeout 10s main
Další typy ukazatelů v 'c' jsou následující:
- Visící ukazatel
- Komplexní ukazatel
- Blízko ukazatele
- Daleký ukazatel
- Obrovský ukazatel
Přímé a nepřímé přístupové ukazatele
V C existují dva ekvivalentní způsoby přístupu a manipulace s proměnným obsahem
- Přímý přístup: používáme přímo název proměnné
- Nepřímý přístup: používáme ukazatel na proměnnou
Pojďme to pochopit s pomocí programu níže
#include <stdio.h> /* Declare and initialize an int variable */ int var = 1; /* Declare a pointer to int */ int *ptr; int main( void ) { /* Initialize ptr to point to var */ ptr = &var; /* Access var directly and indirectly */ printf("\nDirect access, var = %d", var); printf("\nIndirect access, var = %d", *ptr); /* Display the address of var two ways */ printf("\n\nThe address of var = %d", &var); printf("\nThe address of var = %d\n", ptr); /*change the content of var through the pointer*/ *ptr=48; printf("\nIndirect access, var = %d", *ptr); return 0;}
Po zkompilování programu bez jakýchkoli chyb je výsledek:
Direct access, var = 1 Indirect access, var = 1 The address of var = 4202496 The address of var = 4202496 Indirect access, var = 48
Aritmetika ukazatele v C
Operace ukazatele jsou shrnuty na následujícím obrázku
Prioritní operace (přednost)
Při práci s ukazateli C musíme dodržovat následující pravidla priority:
- Operátory * a & mají stejnou prioritu jako unární operátory (negace!, inkrementace++, dekrementace–).
- Ve stejném výrazu se unární operátory *, &,!, ++, – vyhodnocují zprava doleva.
Pokud ukazatel P ukazuje na proměnnou X, pak * P lze použít všude tam, kde lze zapsat X.
Následující výrazy jsou ekvivalentní:
int X =10 int *P = &Y; For the above code, below expressions are true
Výraz | Ekvivalentní výraz |
---|---|
Y=*P+1
*P=*P+10 *P+=2 +**P (*P)++ |
Y=X+1
X=X+10 X+=2 +X X++ |
V druhém případě jsou závorky potřeba: protože unární operátory * a ++ se vyhodnocují zprava doleva, bez závorek by se inkrementoval ukazatel P, nikoli objekt, na který P ukazuje.
Níže uvedená tabulka ukazuje aritmetické a základní operace, které lze použít při práci s C ukazateli
Operavání | Vysvětlení |
---|---|
Přiřazení | int *P1,*P2 P1=P2; P1 a P2 ukazují na stejnou celočíselnou proměnnou |
Inkrementace a dekrementace | Int *P1; P1++;P1– ; |
Přidání offsetu (konstanta) | To umožňuje ukazateli přesunout N prvků v tabulce. Ukazatel se zvýší nebo sníží o N krát počet bajtů (bytů) typu proměnné. P1+5; |
C ukazatele a pole s příklady
Tradičně přistupujeme k prvkům pole pomocí jeho indexu, ale tuto metodu lze eliminovat pomocí ukazatelů. Ukazatele usnadňují přístup ke každému prvku pole.
#include <stdio.h> int main() { int a[5]={1,2,3,4,5}; //array initialization int *p; //pointer declaration /*the ptr points to the first element of the array*/ p=a; /*We can also type simply ptr==&a[0] */ printf("Printing the array elements using pointer\n"); for(int i=0;i<5;i++) //loop for traversing array elements { printf("\n%x",*p); //printing array elements p++; //incrementing to the next element, you can also write p=p+1 } return 0; }
Výstup:
1 2 3 4 5
Přidání konkrétního čísla k ukazateli přesune umístění ukazatele na hodnotu získanou operací sčítání. Předpokládejme, že p je ukazatel, který aktuálně ukazuje na paměťové místo 0, pokud provedeme následující operaci sčítání, p+1, pak se provede tímto způsobem:
Protože p aktuálně ukazuje na místo 0 po přidání 1, hodnota se stane 1, a proto bude ukazatel ukazovat na místo v paměti 1.
C ukazatele a řetězce s příklady
Řetězec je pole objektů typu char, které končí znakem null '\ 0'. S řetězci můžeme manipulovat pomocí ukazatelů. Tento ukazatel v příkladu C vysvětluje tuto sekci
#include <stdio.h> #include <string.h> int main() { char str[]="Hello Guru99!"; char *p; p=str; printf("First character is:%c\n",*p); p =p+1; printf("Next character is:%c\n",*p); printf("Printing all the characters in a string\n"); p=str; //reset the pointer for(int i=0;i<strlen(str);i++) { printf("%c\n",*p); p++; } return 0; }
Výstup:
First character is:H Next character is:e Printing all the characters in a string H e l l o G u r u 9 9 !
Dalším způsobem, jak řešit řetězce, je pole ukazatelů jako v následujícím programu:
#include <stdio.h> int main(){ char *materials[ ] = { "iron", "copper", "gold"}; printf("Please remember these materials :\n"); int i ; for (i = 0; i < 3; i++) { printf("%s\n", materials[ i ]);} return 0;}
Výstup:
Please remember these materials: iron copper gold
Výhody ukazatelů v C
- Ukazatele jsou užitečné pro přístup k paměťovým místům.
- Ukazatele poskytují efektivní způsob přístupu k prvkům struktury pole.
- Ukazatele se používají pro dynamickou alokaci paměti i pro dealokaci.
- Ukazatele se používají k vytváření složitých datových struktur, jako je propojený seznam, graf, strom atd.
Nevýhody ukazatelů v C
- Ukazatele jsou trochu složité na pochopení.
- Ukazatele mohou vést k různým chybám, jako jsou chyby segmentace, nebo mohou přistupovat k místu paměti, které není vůbec potřeba.
- Pokud je ukazateli zadána nesprávná hodnota, může to způsobit poškození paměti.
- Ukazatele jsou také zodpovědné za únik paměti.
- Ukazatele jsou poměrně pomalejší než ukazatele proměnných.
- Pro programátory je velmi obtížné pracovat s ukazateli; proto je zodpovědností programátora manipulovat s ukazatelem opatrně.
Shrnutí
- Ukazatel není nic jiného než paměťové místo, kde jsou uložena data.
- Pro přístup k umístění paměti se používá ukazatel.
- Existují různé typy ukazatelů, jako je nulový ukazatel, divoký ukazatel, void ukazatel a další typy ukazatelů.
- Ukazatele lze použít s polem a řetězcem pro efektivnější přístup k prvkům.
- Můžeme vytvořit ukazatele funkcí pro dynamické vyvolání funkce.
- Aritmetické operace lze provádět na ukazateli, který je známý jako aritmetika ukazatele.
- Ukazatele mohou také ukazovat na funkci, což usnadňuje volání různých funkcí v případě definování pole ukazatelů.
- Chcete-li zpracovat jiný typ dat proměnné, můžete použít typový ukazatel na prázdnotu.