Kezdőoldal » Számítástechnika » Programozás » C/C++: Kétdimenziós sztringtöm...

C/C++: Kétdimenziós sztringtömb átadása függvénynek, mit tudok rosszul?

Figyelt kérdés

Tudom h a gyakorlatban mutatótömböt vagy dinamikus helyfoglalású tömböt használnak, de szeretném ezt is tudni.


Legyen


char name[ 10 ][ 128 ];

int idx = 0;


A scanf() függvényt szeretném meghívni úgy, hogy a name[idx] -be sztringet olvasson be.


scanf( "%s", name[ idx ] );


Nah ezeket jól értem-e?:

A scanf() függvény argumentumként egy mutatót vár, ahova beírja a beolvasott adatot. A name[ idx ] kifejezést a fordító átalakítja *( name + idx ) kifejezéssé. A kétdimenziós tömb olyan egydimenziós tömb, amelynek minden eleme egy további egydimenziós tömb; továbbá a tömb neve a tömb nulladik elemére mutató pointer. Tehát "name" egy char[] tömbre mutat, az idx hozzáadásával és a dereferálással pedig egy char[] tömb első elemére mutató pointert kapunk és ez a kód jól is működik.


Nézzünk egy másik fvhívást:


scanf( "%s", &name[ idx ] );


Amit a fordító erre z alakra hoz elvileg:


scanf( "%s", &*( name + idx ));


Csakhogy az előzőek alapján a *( name + idx ) eredménye egy mutató, aminek a & operátorral lekérjük a címét, és erre a címre fogja a scanf() az adatot írni, ami viszont értelmetlen, mégis ugyanúgy jól működik a kódom, tehát valamit nem értek jól. Mit?


Megköszönném a segítségeteket,

üdv.


2016. febr. 26. 22:20
 1/4 A kérdező kommentje:

Ja és még egy dolog:


Én a következő hívást részesítem előnyben:


scanf( "%s", name + index );


Ami a dereferálás hiánya miatt eltér a name[idx] -től, mégis úgyanúgy működik. (??)

2016. febr. 26. 22:30
 2/4 A kérdező kommentje:

Na megtaláltam a választ a kérdésemre.


C (C99) szabvány (vagy draft):


6.5.3.2 Address and indirection operators


(3)


"If the operand is the result of a unary * operator,

neither that operator nor the & operator is evaluated and the result is as if both were

omitted, except that the constraints on the operators still apply and the result is not an

lvalue."


83) Thus, &*E is equivalent to E (even if E is a null pointer), and &(E1[E2]) to ((E1)+(E2))


Tehát &name[idx] ugyanaz mint name+idx



Annyit mondhatnátok h nagyjából képben vagyok vagy totál rossz úton járok?

2016. febr. 27. 14:12
 3/4 anonim ***** válasza:

Tévhit hogy a tömbök C-ben pointerek, és ebből szoktak jönni a problémák, főleg multidimenziós tömböknél.


A tömbök az ELSŐ szinten pointerré alakulnak kiértékelésnél, illetve egy függvényben ha paraméterkén lettek átadva, de addig nem. És az után is csak EGY szintig, azaz a char[10][128] nem lesz char** és nem lesz char* sem. Az új típusa char(*)[128] lesz. A fordítónak ismernie kell hogy hány bájt hosszú egy elem a tömbben. De van két kivétel! A sizeof() függvény és a & operátor. Ezek még első szinten se alakítják a tömböt pointerré!


Példa hogy a tömb valóban nem pointer: készíts egy függvényt ami 2 dimenziós tömböt vesz át, és hívd meg a name változóddal:


void func(_____) {

return;

}


int main(void) {

char name[10][128];

func(name);

return 0;

}


Mit kell a func paraméterébe írni hogy elfogadja a fordító?

char name[][128]

vagy

char name[10][128]


Más nem fog működni (a 10 megadható, de nem szokás mert itt már pointer az első szinten, viszont a 128 kötelező).


Ok, most hogy ez tisztázva lett, meg kell említeni hogy mivel a tömb nem pointer, máshogy működnek az operátorok is rajtuk. Tömbön pl. nem értelmezett a ++ operátor, a sizeof() függvény mást ad vissza, és a & is bizony a tömb címét fogja visszaadni és nem a tömb első elemének címének címét. Tömbnek nem lehet értéket átadni, de pointernek lehet.


int alma[4];

Az alma típusa int[], éréke az int[0] elem memóriacíme ami egy int* kiértékelve.

De az &alma értéke az alma tömb memóriacíme, így a típusa int(*)[4]!


Ez ugyan úgy igaz lesz multidimenziós tömböknél is.


A C FAQ-ban a 6-os szekciót olvas el ha nem világos, főleg ezt:

[link]

2016. febr. 27. 16:38
Hasznos számodra ez a válasz?
 4/4 anonim ***** válasza:

char name[10][128]


A 10 -es helyén mindegy milyen szám van, char(*)[128] lesz a típusa. Bár ha jól értelmezem pontossan erre céloztál azzal, hogy elhagyható mivel nem számít.


C++ standardból egy részlet:


int f(char*);

int f(char[]); // same as f(char*);

int f(char[7]); // same as f(char*);

int f(char[9]); // same as f(char*);


int g(char(*)[10]);

int g(char[5][10]); // same as g(char(*)[10]);

int g(char[7][10]); // same as g(char(*)[10]);

int g(char(*)[20]); // different from g(char(*)[10]);

2016. febr. 27. 20:36
Hasznos számodra ez a válasz?

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!