Kezdőoldal » Számítástechnika » Programozás » C-ben mi a tömbre mutató pointer?

C-ben mi a tömbre mutató pointer?

Figyelt kérdés
Vegyünk két esetet, mindkettőben a tömbre mutató pointert kell visszaadnunk. Az elsőben egy egy dimenziós dinamikus tömbünk a másodikban egy két dimenziós, amiket malloccal foglaltunk. Kicsit belezavarodtam a pointerekbe, szóval jól gondolom hogy az elsőnél return tomb*, a másodiknál return tomb**?
2020. dec. 1. 09:02
 1/9 anonim ***** válasza:
43%
C/C++ nyelven a tömb maga az első elemére mutató pointerré redukálódik vissza. Szóval ha egy függvényben egy kétdimenziós int tömböt (int**) kell visszaadnod, amelyet a tomb változódban hoztál létre, akkor elég magát a tomb változót visszaadni, mert az már maga egy pointerként kerül kezelésre.
2020. dec. 1. 09:26
Hasznos számodra ez a válasz?
 2/9 A kérdező kommentje:
Tehát mindkét esetben return tomb;? Volt olyan feladat is hogy add vissza a tömböt és olyankor is return tomb; volt.
2020. dec. 1. 09:28
 3/9 anonim ***** válasza:
Igen, mert a tömb típusok az első elemükre mutató pointerek. Egy két dimenziós integer tömb esetén a tömb elemei int* típusúak, tehát a tömb első elemére mutató pointer int** típusú. Egy egy dimenziós esetén int típusúak az eleme, tehát int* az első elemre mutató pointer. Tehát a tömb és a tömb első elemére mutató pointer egymásnak megfeleltethetőek.
2020. dec. 1. 09:36
Hasznos számodra ez a válasz?
 4/9 A kérdező kommentje:
Köszi! Még valami, olyat nem tudok csinálni hogy return tomb* pedig a függvény fejléce int*, olyat viszont enged hogy return *tomb így is jó?
2020. dec. 1. 09:56
 5/9 anonim ***** válasza:
Ha a tomb egy kétdimenziós tömb (int**), ami ugye az első elemére mutató pointer, akkor a *tomb azt jelenti, hogy dereferáljuk a tömb első elemére mutató pointert, vagyis visszaadjuk a mögötte levő értéket. Egy kétdimenziós tömb elemei pedig int* típusúak, tehát a *tomb kifejezés egy int* értéket (a kétdimenziós tömb első sorát) adja vissza.
2020. dec. 1. 10:15
Hasznos számodra ez a válasz?
 6/9 anonim ***** válasza:

Nagyon nem.


Ezt annyiszor félreértik az emberek.


"egy kétdimenziós tömb (int**)"


Nem. A tömb az tömb, a pointer pedig pointer.


Bizonyos kifejezésekben a tömb neve implicit módon első elemre mutató pointerré konvertálódik. A legtöbb kifejezés ilyen, sőt a C szabvány kivételeket sorol fel, amikor ez a konverzió nem történik meg.


int a[5];


a típusa int-ekből álló tömb, ha pl. átadod paraméterként, akkor első elemre mutató pointer adódik át, aminek a típusa int*


int b[5][3];


b típusa kétdimenziós tömb; A b tömbnek 5 eleme van, mindegyik elem egy 3 elemű, int-ekből álló tömb. Ha átadod paraméterként akkor egy első elemre mutató pointer adódik át, ami ez esetben egy 3 elemű, int-ekből álló tömbre mutató pointer, aminek a típusa int(*)[3] // a zárójelek fontosak


[link]


82. oldal


6.5.2.1 Array subscripting 4 EXAMPLE


Ennek fényében void foo(int(*)[3]) a szignatúrája egy függvénynek, ami [][3] méretű tömböt fogad. A tömbös jelölésnél hasonlóan az 1. dimenziós mérete elhagyható, a 2. dimenziós mérete nem. void foo(int a[][3])


Mik a kivételek, amikor ez az implicit konverzió nem megy végbe? Például a sizeof() operátor. sizeof(a) az a tömb méretét adja vissza, nem pedig az első elemének mutatójának méretét.


"Szóval ha egy függvényben egy kétdimenziós int tömböt (int**) kell visszaadnod, amelyet a tomb változódban hoztál létre"


Ez teljesen rossz, mert ha a hívóhoz visszajuttatod egy függvény lokális, stack-en létrehozott tömbjének első elemére mutató pointerét, akkor amikorra a hívó megkapja a visszatérési értéket, a függvény lokális változói destruálódtak. Lehet hogy a memóriaterületen még ott vannak a tömb elemei, de a tömb élettartama véget ért, UB.

2020. dec. 1. 23:59
Hasznos számodra ez a válasz?
 7/9 anonim ***** válasza:

#6 Ha figyelmesen elolvasod a válaszaimat észreveszed, hogy azzal kezdtem a mondandómat, hogy "C/C++ nyelven a tömb maga az első elemére mutató pointerré redukálódik vissza". Nem fogok 6 oldalas paksamétát írni azért, hogy erre a tényre minden hivatkozáskor felhívjam a figyelmet, sem azért, hogy ennek minden elképzelhető kivételét kifejtsem. A tömb gyakorlatilag egy pointerként kerül kezelésre a legtöbb releváns esetben, ennél nem kell mélyebbre menni.


"Ez teljesen rossz, mert ha a hívóhoz visszajuttatod egy függvény lokális, stack-en létrehozott tömbjének első elemére mutató pointerét, akkor amikorra a hívó megkapja a visszatérési értéket, a függvény lokális változói destruálódtak."


És megmutatnád, hogy hol használtam a stack kifejezést? A kérdező maga írta a kérdésben, hogy malloc-al foglalt helyet a tömbjének, innentől a tömb nem a stack-en jön létre, az egyetlen dolog ami a stack-re kerül az maga a pointerváltozó, annak meg visszaadjuk az értékét a függvény végén.


Harmadszor, a kérdés visszatérési típusokra vonatkozik, és habár kopottas a memóriám a nyelvről, de kétlem hogy return type-nak be tudsz vésni egy olyat, hogy int(*)[3]. Nem, egy kétdimenziós integer tömb visszatérési típusa, hacsak nem akarod nagyon flancosra csinálni, int** lesz. És a kétdimenziós tömb arra fog redukálódni.


Nem értettem én semmit félre, csak a kérdésre igyekeztem válaszolni, és nem egy elnyújtott szemináriumot adni olyasmiről, ami a kérdezőt nem érinti/érdekli.

2020. dec. 2. 01:41
Hasznos számodra ez a válasz?
 8/9 anonim ***** válasza:

"Nem fogok 6 oldalas paksamétát írni azért, hogy erre a tényre minden hivatkozáskor felhívjam a figyelmet"


Én is szoktam díjazni azt, amikor vki frappánsan, egyszerűen el tud magyarázni vmit. Ez itt most szubjektív. Véleményem szerint ebben a kérdésben a túlzott egyszerűség miatt az amit leírsz, mást jelent mint amit mondani szeretnél. Ha olyanokat írsz le, hogy "Ha a tomb egy kétdimenziós tömb (int**)" akkor nem meglepő ha félreértik, hiszen a kétdimenziós tömb típusa nem int**.


"És megmutatnád, hogy hol használtam a stack kifejezést? A kérdező maga írta a kérdésben, hogy malloc-al foglalt helyet a tömbjének, innentől a tömb nem a stack-en jön létre"


Ebben teljesen igazad van, bevallom nem olvastam el a kérdés részletezését, ami nem volt korrekt részemről, ezért elnézést kérek, de végigolvasva, meglátásom szerint itt 2 különböző dolog keveredik:


A kérdés: "C-ben mi a tömbre mutató pointer?"


Tömbre mutató pointer egy igazán speciális dolog. A kérdező ezt kérdezte, de mint a részletezésből kiderült, valójában nem erre volt kíváncsi.


A másik dolog, hogy C-ben a malloc/etc által allokált területet inkább nevezik heap/dinamikus tárterület/etc-nek, mintsem "tömbnek". Kapok egy területet, amire azt írok amit akarok, nem is biztos hogy tömbként használom. Attól hogy a tömbindexeléssel is el tudom érni, és nem kell pointer aritmetikában gondolkodni, attól még az nem egy tömb.


"kétlem hogy return type-nak be tudsz vésni egy olyat, hogy int(*)[3]"


ld. a linkelt Stackoverflow kérdés 2. válaszát, de itt egy saját példa:


int (*foo())[3]


{


return malloc(5*3*sizeof(int));


}


Kérdező:


A linkelt Stackoverflow kérdésben az 1. válasz malloc-ol a heapen tárterületet, aminek a kezdő pointerét juttatja vissza a hívóhoz.

2020. dec. 2. 22:56
Hasznos számodra ez a válasz?
 9/9 A kérdező kommentje:
Ez az első félévem egyetemen, most tanulok először programozni, bocsi de nem értek ilyen "foo" dolgokat, én azzal is megelégszem ha megjegyzem hogy mikor mit kell vissza adni (jelenleg 2 eset van ilyen feladatnál) ezért preferálom 7. válaszát inkább. De egyébként rendezzétek le nyugodtan a dolgokat én majd csak figyelek.
2020. dec. 3. 08:08

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!