Ero sivun ”C” versioiden välillä

Poistettu sisältö Lisätty sisältö
Tigru (keskustelu | muokkaukset)
→‎Funktiot: lohkaisen
Tigru (keskustelu | muokkaukset)
→‎Osoittimet: lohkaisen
Rivi 27:
* [[/Funktiot/]]
 
==* [[/Osoittimet ==/]]
 
Jotta voisit ymmärtää osoittimia eli pointtereita, sinun tulee ymmärtää mitä muuttujat ovat ja miten ne sijoittuvat muistissa. Muuttujalla on muistissa paikka, jonne sen arvo on tallennettu. Kun luot muuttujan, muuttuja saa stackista (osa tietokoneen muistia) itselleen tilaa.
 
Osoitin on muuttuja, joka sisältää muistiosoitteen. Yleensä kyseessä on jonkin muun muuttujan osoite muistissa, mutta arvona on usein myös NULL, joka tarkoittaa ettei pointteri osoita minnekään. Osoitinmuuttujan tyyppi kertoo osoitettavan tyypin.
 
Osoitin itse on kooltaan sellainen, että siihen mahtuu mikä tahansa muistiosoite sisälle, usein neljä (32-bittiset arkkitehtuurit) tai kahdeksan (64-bittiset) tavua, mutta et voi tehdä mitään oletuksia tämän pohjalta. Pointterin arvoa ei voi myöskään tallentaa esim. int-tyyppiseen muuttujaan, mutta ruudulle sen voi tulostaa <code>printf</code>:n muotoilusäännöllä <code>%p</code>. osoittimet ja huono osoittimien hallinta voivat aiheuttaa pahoja, vaikeasti havaittavia virheitä. Osoittimien hallinta kannattaa opetella hyvin ennen kuin aloitat ohjelmoimaan C:llä jotakin vakavampaa projektia.
 
[[Kuva:Osoitin.svg|Osoitin.]]
 
<strong>Pointteritietotyyppit</strong> merkitään merkillä <tt>*</tt> osoitettavan tyypin perässä, ennen muuttujaa, eli <tt>float</tt>-tyyppiseen arvoon osoittavan muuttujan tyyppi on <tt>float*</tt>, määrittely esim. <tt>float* p = NULL;</tt>.
 
Muuttujan osoitteen saa selville <tt>&</tt>-operaattorilla, joka laitetaan muuttujan nimen eteen lausekkeessa, jossa osoitetta halutaan käyttää. Ennestään tunnetussa osoitteessa olevaa, eli pointterin osoittamaa, tietoa taasen käytetään laittamalla pointterin eteen operaattori <tt>*</tt>. Älä kuitenkaan sekoita tätä operaattoria <emph>tietotyypissä</emph> käytettäviin <tt>*</tt>-merkkeihin.
 
int x; /* tavallinen muuttuja */
int* y; /* osoitinmuuttuja */
y = &x; /* y sisältää nyt x:n osoitteen */
*y = 32; /* x:n arvo on nyt 32 */
// Testitulosteita
printf(" x = %d\n", x);
printf("&x = %p\n", &x);
printf(" y = %p\n", y);
 
Ohjeita osoittimien käyttöön:
* Osoitin on validi vain niin kauan kuin sen osoittama tieto on olemassa (muistia ei vapautettu muuhun käyttöön).
* Pointtereita käytetään usein tiedon turhan kopioinnin (hidasta) välttämiseksi, mutta jos tietoa on vain hyvin vähän (kuten yksi muuttuja), ei tällä itse asiassa säästetä mitään, sillä itse osoitinkin täytyy kuitenkin kopioida.
* Älä ikinä määrittele useita pointtereita yhdessä lausekkeessa, esim. <tt>int* p1, p2;</tt> on ohjelmointivirhe (p2 ei olekaan pointteri, vaan tavallinen int-tyyppinen muuttuja!).
* Varmista ohjelmasi muistinkäsittelyn toimivuus (myös virheellisillä syötteillä) ensin tutkimalla lähdekoodia huolellisesti, sitten muistivuotodebuggerin avulla.
* Vältä osoittimien käyttöä aina kun järkevästi voit. C-kielessä osoittimet kuitenkin tulevat kaikkialla vastaan, eikä ilman niitä tule toimeen.
 
== Dynaaminen muistinvaraus ==
Noudettu kohteesta ”https://fi.wikibooks.org/wiki/C