Zmienne i wska╝niki 

Strona g│≤wna

 

Zmienne i wska╝niki w C++

W tym artykule dowiesz siΩ z niej o sposobach pos│ugiwania siΩ zmiennymi oraz wska╝nikami w C++.
A wiΩc zaczynamy.

W jΩzyku C++ mo┐na zadeklarowaµ: zmienne, funkcje oraz typy. Na pocz▒tku zajmiemy siΩ zmiennymi oraz sta│ymi.
Sta│a to taka zmienna, kt≤rej warto╢µ mo┐na przypisaµ tylko raz. Z punktu widzenia komputera niewiele siΩ to r≤┐ni, bo miejsce w pamiΩci i tak, stosownie do zadeklarowanego typu zarezerwowaµ trzeba, umie╢ciµ w tablicy i zapamiΩtaµ sobie identyfikator i adres. Jedyna praktyczna r≤┐nica polega na tym, ┐e zmiennej zadeklarowanej jako sta│a, np.:    

const float PI = 3.142;  

nie mo┐na przypisaµ w programie ┐adnej innej warto╢ci, innymi s│owy zapis:

const float PI = 3.14;

jest jednocze╢nie DEKLARACJí, DEFINICJí i ZAINICJOWANIEM sta│ej PI.

Przyk│ad :

float x,y,z; /*DEKLARACJA*/  
const float TEMP = 6.0; /*DEFINICJA*/ 
x = 11; /*ZAINICJOWANIE zmiennej*/ 
Definicja powoduje nie tylko okre╢lenie, jakiego typu warto╢ciami mo┐e operowaµ dana zmienna b▒d╝ funkcja, kt≤ra zostaje od tego momentu skojarzona z podanym identyfikatorem, ale dodatkowo powoduje:
- w przypadku zmiennej - przypisanie jej warto╢ci,
- W przypadku funkcji - przyporz▒dkowanie cia│a funkcji.
Zdefiniujmy dla przyk│adu w│asn▒ funkcje:

Przyk│ad 1.
 
int PokazTekst(void)  
{  
  printf("\nPrzyk│adowy tekst\n");  
  return 0;  
}  
 

--- PODSTAWOWE TYPY DANYCH ---


JΩzyk C/C++ operuje piΩcioma podstawowymi typami danych:
* char (znak, numer znaku w kodzie ASCII) - 1 bajt;
* int (liczba ca│kowita) - 2 bajty;
* float (liczba z p│ywaj▒cym przecinkiem) - 4 bajty;
* double (podw≤jna ilo╢µ cyfr znacz▒cych) - 8 bajt≤w;
* void (nieokre╢lona) 0 bajt≤w.

Zakres warto╢ci przedstawiono w Tabeli poni┐ej.
Podstawowe typy danych w C++.  
________________________________________________________________ 
Typ         Znak      Zakres warto╢ci  
________________________________________________________________ 
char        signed    -128...+127  
int         signed    -32768...+32767  
float       signed    +-3.4E+-38 (dok│adno╢µ: 7 cyfr)  
double      signed    1.7E+-308 (dok│adno╢µ: 15 cyfr)  
void     nie dotyczy  bez okre╢lonej warto╢ci.  
________________________________________________________________ 
(signed - ze znakiem, unsigned - bez znaku.)

--- WSKA¼NIKI ---


Wska╝nik to zmienna, kt≤ra zawiera adres innej zmiennej w pamiΩci komputera. Istnienie wska╝nik≤w umo┐liwia po╢rednie odwo│ywanie siΩ do wskazywanego obiektu (liczby, znaku, │a±cucha znak≤w itp.) a tak┐e stosunkowo proste odwo│anie siΩ do obiekt≤w s▒siaduj▒cych z nim w pamiΩci. Za│≤┐my, ┐e:

x - jest umieszczon▒ gdzie╢ w pamiΩci komputera zmienn▒ ca│kowit▒ typu int zajmuj▒c▒ dwa kolejne bajty pamiΩci, a

px - jest wska╝nikiem do zmiennej x.

Jednoargumentowy operator & podaje adres obiektu, a zatem instrukcja:

px = &x;

przypisuje wska╝nikowi px adres zmiennej x. M≤wimy, ┐e:
px wskazuje na zmienn▒ x lub
px jest WSKA¼NIKIEM (pointerem) do zmiennej x.

Operator * (naz. OPERATOREM WYúUSKANIA) powoduje, ┐e zmienna "potraktowana" tym operatorem jest traktowana jako adres pewnego obiektu. Zatem, je╢li przyjmiemy, ┐e y jest zmienn▒ typu int, to dzia│ania:

y = x;

oraz

px = &x;
y = *px;

bΩd▒ mieµ identyczny skutek. Zapis y = x oznacza:
"Nadaj zmiennej y dotychczasow▒ warto╢µ zmiennej x";
a zapis y=*px oznacza:
"Nadaj zmiennej y dotychczasow▒ warto╢µ zmiennej, kt≤rej adres w pamiΩci wskazuje wska╝nik px" (czyli w│a╢nie x !).
Wska╝niki tak┐e wymagaj▒ deklaracji. Poprawna deklaracja w opisanym powy┐ej przypadku powinna wygl▒daµ tak:

int x,y;
int *px;

Zapis int *px; oznacza:
"px jest wska╝nikiem i bΩdzie wskazywaµ na liczby typu int".

Zwr≤µ uwagΩ, ┐e operatory & i * maj▒ wy┐szy priorytet ni┐ operatory arytmetyczne, dziΩki czemu
* najpierw nastΩpuje pobranie spod wskazanego przez wska╝nik adresu zmiennej;
* potem nastΩpuje wykonanie operacji arytmetycznej; (operacja nie jest wiΩc wykonywana na wska╝niku, a na wskazywanej zmiennej!).

W jΩzyku C++ mo┐liwa jest tak┐e sytuacja odwrotna:

Y = *(pX + 1);

Poniewa┐ operator () ma wy┐szy priorytet ni┐ * , wiΩc: najpierw wska╝nik zostaje zwiΩkszony o 1; potem zostaje pobrana z pamiΩci warto╢µ znajduj▒ca siΩ pod wskazanym adresem (w tym momencie nie jest to ju┐ adres zmiennej X, a obiektu "nastΩpnego" w pamiΩci) i przypisana zmiennej Y.
Taki spos≤b poruszania siΩ po pamiΩci jest szczeg≤lnie wygodny, je╢li pod kolejnymi adresami pamiΩci rozmie╢cimy np. kolejne wyrazy z tablicy, czy kolejne znaki tekstu.

Je╢li dwa wska╝niki wskazuj▒ zmienne takiego samego typu, np. po zadeklarowaniu:

int *pX, *pY;
int X, Y;

i zainicjowaniu:

pX = &X; pY = &Y;

mo┐na zastosowaµ operator przypisania:

pY = pX;

Spowoduje to skopiowanie warto╢ci (adresu) wska╝nika pX do pY, dziΩki czemu od tego momentu wska╝nik pY zacznie wskazywaµ zmienn▒ X. Zwr≤µ uwagΩ, ┐e nie oznacza to bynajmniej zmiany warto╢ci zmiennych - ani wielko╢c X, ani wielko╢µ Y, ani ich adresy w pamiΩci NIE ULEGAJí ZMIANIE. Zatem dzia│anie instrukcji:

pY = pX; i *pY = *pX;

jest R╙»NE a wynika to z priorytetu operator≤w:
najpierw * wy│uskanie zmiennych spod podanych adres≤w, potem = przypisanie warto╢ci (ale ju┐ zmiennym a nie wska╝nikom!).

Shawk <shawk@kki.net.pl