Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: novomente 12. 07. 2020, 11:21:39
-
V knize "Programovací jazyk C" od K&R jsem se dověděl, že pokud je definováno pole:
char a[10]
pak následující výrazy jsou ekvivalentní:
a[i]
*(a+i)
Dále se tam píše, že výraz a[i]
je jazykem C okamžitě převeden na výraz*(a+i)
Je tedy jedno, jakou formu zápisu použijeme. Zajímalo by mě, v jakých případech je vhodné použít ten či onen typ zápisu?
P.S. Když jsem si prohlížel přeložený program do strojového kódu, pak skutečně oba dva zápisy jsou naprosto totožné.
-
Ten první zápis je jen syntaktickým cukrem pro druhý zápis. Který z nich používat? Přece ten, který je přehlednější v daném místě programu. Zpravidla ten první, ale dá se najít mnoho situací, ve kterých je lepší ten druhý.
-
Pokud pracujete s polem, používá se první zápis. Pokud pracujete s ukazateli, používá se druhý zápis. Že je to v C ekvivalentní je „náhoda“, protože jsou tam pole implementovaná pomocí ukazatelové aritmetiky. V jiných jazycích jsou pole implementována jinak, pak ten zápis ekvivalentní není.
Když budete psát nějaký reálný program, tahle otázka vás ani nenapadne.
-
Pochopeni toho proc i[j] je totozne s *(i + j) je naprosto elementarni znalost a doporucuju to pochopit dobre a zapamatovat si to, tyka se to toho jak funguje sprava pameti v C.
*i je pointer na misto v pameti, ktery si muzes nechat interpretovat jako "to je Integer". Potom ti pocitac skoci na misto pameti *i a precte z nej 2 bajty, a pokud udelas *(i + 1), tak pocitac vi, ze ma preskocit 1. 2 bajty, precist 2. 2 bajty a interpetovat je jako Integer.
Ale zrovna tak si muzes libovolne misto v pameti *i nechat interpretovat jako treba Signed char. V tom pripade ti pocitac precte z mista *i 1 bajt.
Pouzivat to muzes treba pro vyrobu vlastnich paketu, kde si muzes do array zakodovat ruzne flagy a data s ruznymi datovymi typy a ruzne delky, poslat si je do nejakeho zarizeni jako bajt hatmatilku, a v tom zarizeni si je zase rozkodovat.
No proste je to dulezite.
A kdyz tak o tom mluvim, tak mam taky dotaz: jak podobu ma v pameti structur? Tipuju ze je to vlastne bajt array, ktere dodrzuje order promennych definovanych ve structure. Tzn. ze si muzu pres pointer na struct jednotlive promenne vytahovat.
-
Pochopeni toho proc i[j] je totozne s *(i + j) je naprosto elementarni znalost a doporucuju to pochopit dobre a zapamatovat si to, tyka se to toho jak funguje sprava pameti v C.
A kdyz tak o tom mluvim, tak mam taky dotaz: jak podobu ma v pameti structur? Tipuju ze je to vlastne bajt array, ktere dodrzuje order promennych definovanych ve structure. Tzn. ze si muzu pres pointer na struct jednotlive promenne vytahovat.
Ad 1: Pointerovou aritmetiku bych fakt správou paměti nenazýval.
Ad 2: Tipovat si nemusíte, není to žádná tajná informace. A tipujete si špatně. Ve výchozím stavu to zaručené nemáte. https://fresh2refresh.com/c-programming/c-structure-padding/
-
Pochopeni toho proc i[j] je totozne s *(i + j) je naprosto elementarni znalost a doporucuju to pochopit dobre a zapamatovat si to, tyka se to toho jak funguje sprava pameti v C.
A kdyz tak o tom mluvim, tak mam taky dotaz: jak podobu ma v pameti structur? Tipuju ze je to vlastne bajt array, ktere dodrzuje order promennych definovanych ve structure. Tzn. ze si muzu pres pointer na struct jednotlive promenne vytahovat.
Ad 1: Pointerovou aritmetiku bych fakt správou paměti nenazýval.
Ad 2: Tipovat si nemusíte, není to žádná tajná informace. A tipujete si špatně. Ve výchozím stavu to zaručené nemáte. https://fresh2refresh.com/c-programming/c-structure-padding/
A proc bych si nemohl tady na foru tipnout, kdyz je to tak uzitecne? Vem si, tipnul jsem si, a nejaky verny otrok me hned opravil a dal mi i odkaz, kde si muzu precist jak to je. A nestalo me to ani tolik praci. Tak proc si v diskuzi cas od casu netipnout? ;)
A pointrova aritmetika, ok, tak neni to sprava pameti, ale je to jednoznacne o tom, jak funguje prace s pameti v jazyce C.
Takze ted vim, ze kdyz si chci zakodovat data do paketu a poslat si je do nejakeho zarizeni, tak na to nemam pouzivat struct, ale bajt array, jako jsem to vzdycky delaval. Takze jsem to delal dobre.
Jo ale mozna pres tu pragmu uz by to slo no:
#pragma pack(1)
struct structure1
{
int id1;
int id2;
char name;
char c;
float percentage;
};
Coz mi pripomina ozehavy problem v kompatibilitie mezi little endianem a big endianem mezi ruznymi zarizenimi. No, jeste ze uz v C nedelam a na Arduino uz nikdy cas mit nebudu...
-
Takze ted vim, ze kdyz si chci zakodovat data do paketu a poslat si je do nejakeho zarizeni, tak na to nemam pouzivat struct, ale bajt array, jako jsem to vzdycky delaval. Takze jsem to delal dobre.
Nikoli, je daleko lepší použít struct. Ovšem musíte to umět používat správně.
-
Ono je to ještě jednodušší. Název pole je ve skutečnosti jenom zástupný symbol pro ukazatel na jeho počátek, takže pouhé
a
pro překladač znamená
&(a[0])
Proto se pole funkcím předávají vždy jako ukazatele, což je v té knize také.
A třeba
a[10]
je
*(int*)((int) &(a[0]) + (10 * sizeof(int)) )
Za předpokladu že pole a je typu int.
Už máš jasno který zápis je vhodné používat? ;D
-
Coz mi pripomina ozehavy problem v kompatibilitie mezi little endianem a big endianem mezi ruznymi zarizenimi. No, jeste ze uz v C nedelam a na Arduino uz nikdy cas mit nebudu...
man htonl
man htons
Edit: k původní otázce - pište tak abyste se v tom vyznal i za půl roku (a pokud možno pro podobné případy konzistentně) a bude to OK.
-
Pokud pracujete s polem, používá se první zápis. Pokud pracujete s ukazateli, používá se druhý zápis. Že je to v C ekvivalentní je „náhoda“, protože jsou tam pole implementovaná pomocí ukazatelové aritmetiky. V jiných jazycích jsou pole implementována jinak, pak ten zápis ekvivalentní není.
Když budete psát nějaký reálný program, tahle otázka vás ani nenapadne.
Myslim, ze tohoto se budu drzet. Jestli nastane nejaka vyjimka v jazyce C, tak jestli je naprosto jedno, ktery zapis pouziji, pak budu preferovat prehlednost a srozumitolnost zapisu v danem kontextu zdrojoveho kodu.
Dekuji vsem za uzitecne odpovedi.
-
A kdyz tak o tom mluvim, tak mam taky dotaz: jak podobu ma v pameti structur? Tipuju ze je to vlastne bajt array, ktere dodrzuje order promennych definovanych ve structure. Tzn. ze si muzu pres pointer na struct jednotlive promenne vytahovat.
Hledáš offsetof (https://man7.org/linux/man-pages/man3/offsetof.3.html).