Preferovaný zápis jména pole jako ukazatele

Preferovaný zápis jména pole jako ukazatele
« kdy: 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:
Kód: [Vybrat]
char a[10]pak následující výrazy jsou ekvivalentní:
Kód: [Vybrat]
a[i]
*(a+i)

Dále se tam píše, že výraz
Kód: [Vybrat]
a[i] je jazykem C okamžitě převeden na výraz
Kód: [Vybrat]
*(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é.


Kit

  • ****
  • 475
    • Zobrazit profil
    • E-mail
Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #1 kdy: 12. 07. 2020, 11:39:04 »
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ý.

Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #2 kdy: 12. 07. 2020, 12:05:10 »
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.

Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #3 kdy: 12. 07. 2020, 12:09:34 »
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.
« Poslední změna: 12. 07. 2020, 12:15:24 od PetrK »

robac

  • ***
  • 110
    • Zobrazit profil
    • E-mail
Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #4 kdy: 12. 07. 2020, 12:28:31 »
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/


Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #5 kdy: 12. 07. 2020, 12:33:13 »
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:

Kód: [Vybrat]
#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...
« Poslední změna: 12. 07. 2020, 12:37:35 od PetrK »

Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #6 kdy: 12. 07. 2020, 13:49:47 »
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ě.

Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #7 kdy: 12. 07. 2020, 15:05:52 »
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é
Kód: [Vybrat]
apro překladač znamená
Kód: [Vybrat]
&(a[0])Proto se pole funkcím předávají vždy jako ukazatele, což je v té knize také.

A třeba
Kód: [Vybrat]
a[10]je
Kód: [Vybrat]
*(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

Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #8 kdy: 12. 07. 2020, 16:21:18 »
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.
« Poslední změna: 12. 07. 2020, 16:23:13 od J ouda »

Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #9 kdy: 14. 07. 2020, 15:50:25 »
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.

Re:Preferovaný zápis jména pole jako ukazatele
« Odpověď #10 kdy: 14. 07. 2020, 16:45:03 »
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.