Olen nyt opiskellut tuota C-ohjelmointia, yksi vaikea asia tuli eteen nimeltänä osoittimet, niitä en suostu ymmärtämään. Eli siis mitä eroja osoittimissa on & ja * merkkejä käyttäen?
int *a; // osoitin int-tyyppiseen muuttujaan int b; // int-tyyppinen muuttuja. ;) int& c = b; // viittaus int-tyyppiseen muuttujaan, ei suinkaan mikään osoitin. Se pitää alustaa heti tässä ja nyt. Se on C++:aa, ei C:tä. a = &b; // osoitin = b:n osoite. a = &c; // osoitin = b:n osoite, viittaus on näinkin kiinteä juttu. Se on yhä kuitenkin vain C++:aa, ei C:tä.
& viittaa muuttujan muistiosoittimeen kun taas * on osoitin merkki.
esim.
int *os; /*int tyyppinen osoitin muuttuja*/ int i; /*muuttuja*/ os = &i; /*Nyt osoitin sisältää i -muuttujan muistiosoitteen*/ *os = 10; /*os osoittaa [b]i[/b]hin, jonka arvo on nyt 10*/
Tietokoneen muistissa jokaisella sinne tallennetulla tiedolla on oma osoite. Esim. jos ohjelmassa on muuttujat a, b ja c, ne voivat sijaita muistissa vaikka kohdissa 100, 200 ja 300.
Merkki & kertoo, missä kohdassa muistia muuttuja on. Tässä tapauksessa &a olisi 100, &b olisi 200 ja &c olisi 300.
Osoitin ilmoittaa jonkin muuttujan osoitteen muistissa. Jos osoitin viittaisi muuttujaan a, sen arvo olisi siis 100.
Merkki * osoittimen edessä tarkoittaa muuttujaa, johon osoitin viittaa. Jos osoittimen o arvo olisi 100, *o olisi siis muuttuja a.
Merkki * tarkoittaa lisäksi muuttujan määrittelyssä, että sen jälkeen tuleva muuttuja on osoitin.
Tässä on testiohjelma:
#include <stdio.h>
int main(void) {
/* kolme tavallista muuttujaa */
int a = 1, b = 2, c = 3;
/* kaksi osoitinmuuttujaa */
int *o, *p;
/* tulostetaan muuttujien arvot */
printf("Muuttujat: %i %i %i\n", a, b, c);
/* tulostetaan muuttujien osoitteet */
printf("Osoitteet: %i %i %i\n", &a, &b, &c);
/* osoitin o osoittaa muuttujaan a */
o = &a;
/* tulostetaan osoittimen arvo */
printf("Osoitin (o): %i\n", o);
/* tulostetaan muuttujan arvo */
printf("Muuttuja (*o): %i\n", *o);
/* muutetaan muuttujan arvoa */
*o = 4;
/* tulostetaan muuttujan arvo */
printf("Muuttuja (*o): %i\n", *o);
/* nyt myös a on muuttunut */
printf("Muuttuja (a): %i\n", a);
/* osoitin o osoittaa muuttujaan b */
o = &b;
/* osoitin p osoittaa samaan muuttujaan */
p = o;
/* tulostetaan osoittimen arvo */
printf("Osoitin (p): %i\n", p);
/* tulostetaan muuttujan arvo */
printf("Muuttuja (*p): %i\n", *p);
/* nyt myös *o on muuttunut */
printf("Muuttuja (*o): %i\n", *p);
/* nyt myös b on muuttunut */
printf("Muuttuja (b): %i\n", *p);
return 0;
}Minulla ohjelma tuotti seuraavan tulosteen:
Muuttujat: 1 2 3 Osoitteet: 2293596 2293600 2293604 Osoitin (o): 2293596 Muuttuja (*o): 1 Muuttuja (*o): 4 Muuttuja (a): 4 Osoitin (p): 2293600 Muuttuja (*p): 2 Muuttuja (*o): 2 Muuttuja (b): 2
Minun koneellani muistin kohdissa 2293596, 2293600 ja 2293604 sattui siis ohjelman ajohetkellä olemaan vapaata tilaa kolmelle muuttujalle.
Metabolix kirjoitti:
int& c = b; // viittaus int-tyyppiseen muuttujaan, ei suinkaan mikään osoitin. Se pitää alustaa heti tässä ja nyt.
Kysyjä puhui C:stä, C:ssä ei ole esittämiäsi viitemuuttujia (C++:ssa on). Koodisi on siis C++:aa eikä C:tä.
Jos käyttää GNU:n C-kääntäjää, hyvä konsti standardinmukaisen C:n kirjoittamiseen on antaa gcc-komennon parametreiksi -Wall, -std=c89 tai -std=c99 ja -pedantic.
-Wall: tulosta kaikki virheilmoitukset
-std=xxx: mitä C:n standardia noudatetaan
-pedantic: ollaan nirsompia
Kas, niinpä puhuikin, luin vain itse kysymyksen. Mutta tulipa siinäkin yksi käyttö &-merkille, eihän siitä haittaakaan ole, tuli selväksi, että int& ei ole osoitin. Muokkasin sinne maininnan tästä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.