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
 11/16 A kérdező kommentje:
Rosszul következtettem, a francba. Értékadás során a balérték nem mozog a területen így a tesztem nem jelent semmit.
2013. júl. 12. 18:57
 12/16 anonim ***** válasza:

#9

1. Korrekt.


2. Korrekt.

Ha pl. azt mondjuk, hogy

__char* ptr;

__printf("%d", *ptr);

akkor a *ptr kifejezés egyetlen (sizeof(char)) bájtot fog kiolvasni a ptr által tárolt címről.

__int* ptr;

__printf("%d", *ptr);

Ez pedig a ptr-ben lévő címtől kezdve sizeof(int) darab bájtot olvas ki, és int-ként kezeli. Tehát ha pl. a ptr-ben 100-as cím volt, akkor a 100,101,102,103-as címeken lévő értékeket kezeli egyetlen int-ként.


3. "A "var" szimbólum létezik a C/C++ programban"

Ezt most nem vágom. Az általános típusú változóra gondolsz, mint ami pl. Visaul Basicben is van? Erről nem tudok C-ben. Pontosabban vannak ilyen megoldások, de nem részei az alap C/C++ szabványnak. (Ha jól tudom...)


"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?"

Igen, pontosan ezt teszi. A statikus változók címét fordításkor már tudjuk, így a fordító (pontosabban a szerkesztő/linker) simán berakja a helyére a konkrét címet.

A dimamikus változók/objektumok címére meg nem szoktunk & operátort használni, hiszen eleve tároljuk valahol (egy pointerben) a címüket. :)


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

Huh, ennek utána kellett néznem, mert hirtelen én sem tudtam.

"When applied to functions or l-values, the result of the expression is a pointer type (an r-value) derived from the type of the operand. For example, if the operand is of type char, the result of the expression is of type pointer to char. The address-of operator, applied to const or volatile objects, evaluates to const type * or volatile type *, where type is the type of the original object."

[link]

Szóval igen, olyan típusos pointert ad vissza, amilyen típusú változóra használtuk.


#10

Az & operátor nem hoz létre változót, nem foglal területet.

Ha pl. ezt mondjuk:

__char ch = 0; // mondjuk a 100-as címen van a ch

__printf("%d", ch);

akkor a printf-ben lévő ch hivatkozás valahogy így fog kinézni (nem vagyok nagy assembly guru, szóval csak Z80-szerű kóddal) :

__LD A,(100)

__PUSH A

vagyis a 100-as címről tölt valamelyik regiszterbe, és onnan kerül majd paraméterként a printf függvényhez.

Ha meg így van:

__printf("%d", &ch);

Akkor erre fordul:

__LD A,100

__PUSH A

vagyis simán a cím adódik át a printf-nek. :)


(Csak zárójelben jegyzem meg, hogy a "sizeof()" sem egy meghívandó függvény, hanem olyan operátor, amit a fordító lecserél a konkrét értékre. Azért praktikus, mert a platformtól függ, hogy mire cseréli, de ezt a fordító tudja, hogy épp milyen platformra/architektúrára fordít.)

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

Nagyon-nagyon köszönöm a segítségedet, mostmár teljesen érthető :)


Ha megengeded egy kérdésem még lehet ezzel a Z80 kóddal kapcsolatban?


LD A,(100)


Ha jól sejtem az A egy változó vagy regiszter lesz, az LD memóriaterületről betöltést jelent (LOAD), és akkor pedig a , utáni értéket tölti bele. A () pedig a benne lévő memóriacímen tárolt értéket adja vissza ugye?


Mégegyszer nagyon köszönöm a segítségedet :D Üdv

2013. júl. 13. 10:41
 14/16 iostream ***** válasza:
100%

"Igen, pontosan ezt teszi. A statikus változók címét fordításkor már tudjuk, így a fordító (pontosabban a szerkesztő/linker) simán berakja a helyére a konkrét címet.

A dimamikus változók/objektumok címére meg nem szoktunk & operátort használni, hiszen eleve tároljuk valahol (egy pointerben) a címüket. :)"


Ehhez csak annyit, hogy előfordul nem stacken lévő objektumok címének elkérése, például referenciaként átadott változó:

void* f(int& x)

{

return &x;

}


Így persze sok értelme nincs a kódnak, de előfordul, hogy haszna vagyon neki.


Ahhoz meg, hogy lesz-e külön változó a & eredményéből, az a fordító döntése. Lehet, hogy igen, meg lehet hogy nem. Ez színtisztán optimalizációs kérdés, bízd rá.


Amúgy nagyon szép magyarázat volt, a kérdező meg még meg is értette, nagy gratuláció mindkettőtöknek :)

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

81%: Közben utánanéztem, Assembly-ben az utolsó kérdéses Z80-as kód így néz ki:


MOV A, [100]


Vagyis elvileg jól értelmeztem.


iostream: Köszönöm a kiegészítésed és a gratulációt. Itt gyk-n eddig ez a 2. dicséretem tőled :D


Üdv

2013. júl. 13. 21:08
 16/16 anonim ***** válasza:

"LD A,(100)

Ha jól sejtem az A egy változó vagy regiszter lesz, az LD memóriaterületről betöltést jelent (LOAD), és akkor pedig a , utáni értéket tölti bele. A () pedig a benne lévő memóriacímen tárolt értéket adja vissza ugye?"


Teljesen jól leírtad, az A a Z80 procinak az egyik regisztere, és az LD a 100-as címről tölt be egy bájtot az A-ba. Tehát az A nem a memórában van, nincs címe.

(Nem mintha túl sokan foglalkoznának manapság a Z80 processzorral, de én csak ebbe folytam bele annak idején. Arra akartam példát mutatni, hogy a lefordított kód néha nem olyan bonyolult, mint hinnénk, és nincs mindig szükség extra "változókra". :D)


Amúgy köszi az elismerést, pláne hogy iostream kicsit jobban képben van, mint én. :)

2013. júl. 14. 13:02
Hasznos számodra ez a válasz?
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!