Kezdőoldal » Számítástechnika » Programozás » C/C++ Kérdés a void pointerekről?

C/C++ Kérdés a void pointerekről?

Figyelt kérdés

1. sizeof(void) -ra fordítási hibát ad. Miért?


2.

int x;

void * ptr = &x;

Itt a ptr nem jelöl ki memóriaterületet (könyv szerint). Ez mit jelent pontosan? Ha nem void pointert használok akkor a memóriaterületen létrejön egy pointer ami vhova mutat. A ptr számára nem jön létre külön pointerváltozó? De akkor ez azt jelentené hogy fordítási időben "létezik"?


3. Változót void típussal van értelme használni, vagy csak pointerek esetében?


void var;


Megköszönném ha segítenétek. Üdv


2013. júl. 12. 15:47
1 2
 1/16 anonim ***** válasza:
1. A void nem egy konkrét típus, hanem a típus-nélküliségre (pl. pointer) vagy a típusmegadás szükségtelenségére (függvény visszatérő adat nélkül) utal. A sizeof egy típust vár, így a "sizeof(void)" értelmetlen. Mit szerettél volna vele? :)
2013. júl. 12. 16:06
Hasznos számodra ez a válasz?
 2/16 anonim ***** válasza:

2. A ptr pointer változónak lefoglalódik egy új memóriaterület, és az x változó címe kerül bele.

-- "A ptr számára nem jön létre külön pointerváltozó?"

A ptr maga a pointer változó. A ptr memóriacímére itt most nem mutat semmi, pontosabban a "ptr" szimbólum hivatkozik rá, és ahol felhasználod, oda belefordítódik az a cím. De ez a cím nem változó, hanem egy konstans érték.

2013. júl. 12. 16:13
Hasznos számodra ez a válasz?
 3/16 A kérdező kommentje:

És mi a helyzet a sizeof(void*) -al? Ez lefordul, és 4 -et ad vissza.


De a fő kérdésem a 2-es. A void* mutatók ha nem jelölnek ki tárolót, akkor csak fordítási időben fejtik ki hatásukat?


3. Változót void típussal van értelme használni, vagy csak pointerek esetében? (tudom-tudom függvények, de ezen túlmenően akkor void típusú változókat nemigen használunk?)

2013. júl. 12. 16:15
 4/16 A kérdező kommentje:

"De ez a cím nem változó, hanem egy konstans érték."


A cím típusú adat nem egy pointer? Én úgy tudom.

2013. júl. 12. 16:18
 5/16 anonim ***** válasza:

3. A void nem típus. Pointerek esetében azt jelenti, hogy a pointer által mutatott byte-on nincs meghatározott típusú adat, vagyis tíőus nélküli pointer. De amúgy pointer, tehát a pointer típusú, csak a mutatott adat nincs deklarálva.


void var;


A fordító ilyenkor létrehoz magának egy "var" szimbólumot, és a típusának megfelelő méretű memóriát "foglal le". (Azért idézőjelben, mert majd csak a linker fogja a szimbólumokat konkrét címekre cserélni.) Viszont a lefoglalt méretre már a fordítónak is szüksége van, enélkül nem tud relatív hivatkozásokat sem létrehozni. Mivel a void nem típus, ezért mérete sincs.


A pointer azért lehet void*, mert az "csak" egy olyan változó, ami egy címet tárol. (Ezáltal mutat arra a címre.) Címet tárolni meg anélkül is lehet, hogy tudnánk mi van azon a címen.


Egyébként az 1. pontban nem sizeof(void*)-ot akartál írni?

2013. júl. 12. 16:22
Hasznos számodra ez a válasz?
 6/16 anonim ***** válasza:

Na, addig gépeltem, hogy nem is láttam, amit írtál. :)


"A void* mutatók ha nem jelölnek ki tárolót, akkor csak fordítási időben fejtik ki hatásukat?"


A mutató (pointer) olyan változó, ami egy címet tárol. Ez leggyakrabban 4 bájtos (32 bites) cím, ezért kapsz 4-et a sizeof(void*)-ra. Azt a méretet adja vissza, ahány bájton a címet tárolja.


Nem tudom, mit értesz azon, hogy "tárolót jelöl ki". Talán arra gondolsz, hogy mutat valahova, de ez nem jelent feltétlenül memóriafoglalást, csaj egy cím tárolását.

A pointer pedig egy típus. Nincs külön típusneve, tehát nem tudsz olyat mondani, hogy 'pointer p;', ehelyett azt a típust adjuk meg, ami típusú adat a mutatott helyen van. Ha nem akarjuk ezt magadni, akkor lehet void*-ot írni. A void szimbólum csak annyit jelent, hogy nem adunk meg típust, tehát a void* egy olyan pointer, ami pl. egy ismeretlen adatra mutat.

(Remélem a kérdésre válaszoltam. :D)

2013. júl. 12. 16:29
Hasznos számodra ez a válasz?
 7/16 anonim ***** válasza:

"A cím típusú adat nem egy pointer? Én úgy tudom."

Azt nem arra írtam, félreértettél. A pointer egy cím típusú adat, igen. A pointer egy címet tárol. (Én a ptr szimbólumról írtam, de csak mellékesen.:))

2013. júl. 12. 16:32
Hasznos számodra ez a válasz?
 8/16 anonim ***** válasza:

"A void* mutatók ha nem jelölnek ki tárolót, akkor csak fordítási időben fejtik ki hatásukat?"


Na jó, kezdem érteni, mire gondolsz. :)


Ha azt mondom, hogy

<típus/void> * változónév;

akkor létrejön egy pointer. Lefoglalódik neki (a te gépeden legalábbis) 4 bájt. Akkor is, ha int*, char*, vagy void*.


Az, hogy mi a típus a '*' előtt, az szól a fordítónak. Amúgy futásidőben mindegyik ugyanolyan cím lesz. A típus fogja viszont megmondani, hogy fordításkor hogyan kezelje pl. a *ptr hivatkozásokat. Ha int* típusú volt, akkor a mutatott helyről int-et olvas ki. Vagy ha egy int tömb első elemére mutat, és te a második elemet akarod kiolvani, akkor tudnia kell a fordítónak, hogy a mutatóhoz sizeof(int)-et kell hozzáadni, hogy a második elemre mutasson. Ezek fordításkor dőlnek el, és fixen kerülnek a kódba. Futásidőben már csak sima pointerek vannak, minden más be van "égetve" a kódba. :)


De a lényeg, hogy a void* is ugyanúgy memóriát foglal, tehát futáskor lefoglalódik neki is a 4 bájt.

2013. júl. 12. 16:42
Hasznos számodra ez a válasz?
 9/16 A kérdező kommentje:

Igen, a félreértést a "tárolót jelöl ki" kifejezés semmitmondósága okozza, de akkor ha jól értem, helyesek a következő összegzések?


1. A mutató tehát egy változó, aminek értéke egy memóriacím. A memóriacím alacsony szinten "számérték" (4 bájtos, típustól függetlenül) míg C/C++ kódokban egy pointer típus reprezentálja. (tudom az hogy hány bájtos a memóriacím implementációfüggő, jelen esetben win32).


2. A nem egyértelmű kifejezés miatt nekem először úgy jött le hogy a void* típusú változó nem jön létre a memóriaterületen, csak fordítási időben van jelentősége, de ezzel szemben akkor ugyanúgy 4 bájt hosszon létezik a létrejövő program kódjában. Típus nélkülisége miatt pedig a rá történő hivatkozáskor "tetszőleges" hosszúságú memóriaterület feldolgozható, ez a típuskonverziótól függ, ugye? Ezzel szemben az olyan mutatók amelyeket alaptípussal definiálunk mindig meghatározott hosszúságú memóriaterületet dolgoznak fel. Jól értem?


3.

void var;

A "var" szimbólum létezik a C/C++ programban (ezért tehát pl nem lehet újabb "var" azonosítót definiálni) viszont mivel nincs típusa végeredményben nem jön létre változó?


Végezetül egy utolsó kérdésem van ami nem a void-al kapcsolatos de idevág:


A "címe" & művelet az adott objektum memóriacímét adja vissza. C/C++ban a memóriacímeket pointerek reprezentálják, ez azt jelenti hogy visszaad egy pointert, aminek értéke az objektum memóriacíme (úgyis mondhatjuk hogy az objektum címére mutat).


pointer = &variable;


A konkrét kérdésem, hogy az a pointer amit a & művelet visszaad az külön létrejön a memóriaterületen? Vagy a fordító van annyira intelligens és fölöslegesen nem hoz létre újabb pointert hanem egyszerűen a "pointer" változó értékét írja át az adott címre?


A & által visszaadott pointer típusa pedig automatikusan olyan típusú, amilyen kifejezésben használták a & kifejezést?


Azért érdekel ennyire, mert a könyveim annyit írnak hogy "az objektum címét adja vissza", de ez nemsok minden.


Nagyon köszönöm a segítségedet, üdv

2013. júl. 12. 17:45
 10/16 A kérdező kommentje:

Kipróbáltam:


// compiler: gcc



#include <cstdlib>

#include <cstdio>



int main()

{

int x = -2;

int* pointer;

printf( "(1) A pointer valtozo memoriacime: %d \n", &pointer );

pointer = &x;

printf( "(2) A pointer valtozo memoriacime: %d \n", &pointer );

printf( "Az x valtozo memoriacime: %d \n", &x );

getchar();

return 0;

}


// eof


(1) A pointer valtozo memoriacime: 2293576

(2) A pointer valtozo memoriacime: 2293576

Az x valtozo memoriacime: 2293580


Mivel a & művelet pointert ad vissza logikusnak tűnt hogy úgymond "új pointert hoz létre" és azt adja vissza, a balérték pedig "felülíródik az új pointerrel", de mivel ugyanott maradt a memóriaterületen ezért a második verzió a helyes ugye? Tehát a pointer = &variable művelet a pointer értékét írja át.


Bocsi hogy túlbonyolítom :D

2013. júl. 12. 18:00
1 2

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!