Jak funguji promenne a pointery v C – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Jak funguji promenne a pointery v C – C / C++ – Fórum – Programujte.comJak funguji promenne a pointery v C – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
....
~ Anonymní uživatel
4 příspěvky
24. 12. 2011   #1
-
+1
-
Zajímavé

Ahoj,

v jazyce C uz 'programuji' nejaky ten patek, a tak me celkem zajima, jak kompilator vyhodnocuje ci prevadi promenne. Jako spravny c-programator uz vidim vsude jen pointery, pointery, pointery na pointery a celkem mi to leze i na hlavu (coz je mozna dobre).

Kdyz nadefinujeme promennou i (integer a na libovolne adrese, tedkom je to celkem jedno), do ktere pak  vlozime hodnotu 5. Udelame to jednoduse i=5, ale jak to vidi kompilator? Vim, ze pointer nebo pole (napr. pole[5]) deklarovanim (pole) ziskame jen adresu pocatecniho prvku (&pole[0]). Kdyz bychom chteli na danou adresu vlozim hodnotu 8, museli bychom udelat *pole=8.

A tak se ptam, jak tedy funguje jen samotna promenna (ne pole ani pointer)? Prepise misto i=5 kompilator *(&i)=5 (vloz na adresu v pameti napr. 0x54f2 hodnotu 5) ? Nebo jak? Jak takoveto promenne obecne funguji? Drive me to vubec nenapadlo (prislo mi to matematicky moc trivialni - bohuzel matematika nealokuje promenne :] ), ale ted uz me to celkem zajima. Kdyby mi to nekdo vysvetlil, tak bych mu byl moc vdecny. Preji hezke vanocni svatky vsem a dekuji za odpovedi.  

Nahlásit jako SPAM
IP: 217.115.249.–
Reklama
Reklama
zlz
~ Anonymní uživatel
634 příspěvků
24. 12. 2011   #2
-
0
-

Jo, je to přesně tak. Překladač ví, kde tu proměnnou má a to přiřazení přeloží jako zápis na danou adresu.

Nahlásit jako SPAM
IP: 213.211.51.–
....
~ Anonymní uživatel
4 příspěvky
24. 12. 2011   #3
-
0
-

Aha! Dekuji moc, ze jste mi mou uvahu potvrdili a objasnili situaci. Jsem Vam moc vdecny.

Nahlásit jako SPAM
IP: 217.115.249.–
zlz
~ Anonymní uživatel
634 příspěvků
24. 12. 2011   #4
-
0
-

Akorát to teda nemusí být přímá adresa, ale třeba u lokálních proměnných, které se ukládají na zásobníku se na začátku funkce zjistí aktuální pozice/adresa na zásobníku a to přiřazení bude něco jako zasobnik[offset_i] = 5.

Nahlásit jako SPAM
IP: 213.211.51.–
....
~ Anonymní uživatel
4 příspěvky
24. 12. 2011   #5
-
0
-

Muzu se teda jeste zeptat, co tim myslite aktualni adresa v zasobniku? To jako, kdybychom definovali promennou (int) i=3,u=5,h=12, tak to kompilator vyhodnoti jako zasobnik[0]=3,[1]=5,[2]=12? Tim padem by adresa promennych i,u,h byla odlisna jen o 1cku (jak je to v pointerove aritmetice prvku), ne?  A co kdyby jedna promenna byla typu float? To by se musel vytvorit novy zasobnik typu float? Doufam, ze Vam tyhle dotazy nepripadaji stupidni, ale me to hodne pomaha se v tom orientovat, dekuji.

Nahlásit jako SPAM
IP: 217.115.249.–
zlz
~ Anonymní uživatel
634 příspěvků
24. 12. 2011   #6
-
+1
-
Zajímavé

To budu muset vzít trochu ze široka.

Nemá smysl pro každou lokální proměnnou každé funkce rezerovat samostatný kousek paměti (adresu). Jednak by to bylo plýtvání a taky by pak nefungovala třeba rekurze (nebo by se to muselo nějak speciálně řešit).

Takže si každá funkce to místo pro své lokální proměnné alokuje za běhu.

No a tím, že lokální proměnné existují jen uvnitř dané funkce a jednotlivé funkce se postupně zanořují, tak se na to hodí právě zásobník. Klasika, last-in-first-out.

Takže ten zásobník je prostě rezervovaný kus paměti, ze kterého se postupně "ukusují" a zase "uvolňují" kousky tak, že se na začátku funkce zjistí aktuální "vrchol" zásobníku a o kousek se posune a na konci funkce se zase posune zpátky. A mezi tím se pracuje s tím dočasně ukousnutým kusem.

http://en.wikipedia.org/wiki/Stack-based_memory_allocation

Co, se týče těch dat, tak na jejich typu nezáleží. Zásobník je jen jeden (pro každé vlákno) a každá proměnná v něm zabírá kousek. Překladač s nimi podle jejich typu pracuje (generuje instrukce procesoru), ale jinak je to prostě kus paměti.

Takže ano, ty tři inty nejspíš budou v řadě za sebou i s tím floatem. Ale třeba chary už nejspíš ne, protože přístup na "zarovanné" adresy je rychlejší. Takže pokud int a float mají 4 byty a char 1 byte, tak toto: 

int a, b; char c, d; float e;

může být po bytech uspořádáno třeba takhle:

a1,a2,a3,a4,b1,b2,b3,b4,c,_,_,_,d,_,_,_,e1,e2,e3,e3

Nebo může překladač usoudit, že vůbec nemá smysl držet nějakou hodnotu v proměnné/paměti (přístup k paměti je poměrně pomalý) a vygeneruje kód s konstantou, apod.

Nahlásit jako SPAM
IP: 213.211.51.–
....
~ Anonymní uživatel
4 příspěvky
24. 12. 2011   #7
-
0
-

Dekuji, ze jste mi to, ac po lopate, tak velmi hezky a pochopitelne, vysvetlil. Ten clanek stoji urcite zato precist. Jeste jednou velke diky, ze jste si na me behem vanocnich svatku udelal cas.

Nahlásit jako SPAM
IP: 217.115.249.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 231 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý