C - struct vnořování – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

C - struct vnořování – C / C++ – Fórum – Programujte.comC - struct vnořování – C / C++ – Fórum – Programujte.com

 

Axinox
~ Anonymní uživatel
2 příspěvky
28. 3. 2021   #1
-
0
-

Dobrý den,

prosím o radu. Mám založenou strukturu kde posílám data po sběrnici. Mám tam položky délka dat, data jako pole 8 bajtů, identifikátor atd.. No a potřeboval by jsem nějak udělat aby jsem mohl přistupovat do struktury tak, aby jsem mohl přistupovat ke každému bajtu dat zvlášť a pak na ten bajt další strukturu, aby jsem tam mohl vyplňovat data který mají určenou pozici v tom bajtu.

Nahlásit jako SPAM
IP: 5.102.63.–
gna
~ Anonymní uživatel
1891 příspěvků
29. 3. 2021   #2
-
+1
-
Zajímavé
Kit +

Velikost členů jde určit v bitech a členy unionu se překrývají. Tak si to můžeš podle potřeby nějak nakombinovat. (Mimo toho, že to všechno můžeš kdykoliv explicitně přetypovávat.) Podle způsobu použití to může formálně být nedefinované, nebo implementačně závislé chování, ale funguje to prakticky všude. 

struct magic {
	union {
		uint16_t w;
		struct { uint8_t b1, b2; } b;
		struct { uint16_t n1:4, n2:4, n3:4, n4:4; } n;
	};
};

int main()
{
	struct magic m = { 0x1234 };
	printf("sz %zu\n", sizeof(m));
	printf("w %x\n", m.w);
	printf("b %x %x\n", m.b.b1, m.b.b2);
	printf("n %x %x %x %x\n", m.n.n1, m.n.n2, m.n.n3, m.n.n4);
}
/*
sz 2
w 1234
b 34 12
n 4 3 2 1
*/
Nahlásit jako SPAM
IP: 213.211.51.–
JerryM
~ Anonymní uživatel
649 příspěvků
29. 3. 2021   #3
-
0
-

#1 Axinox
jestli máš ten přístup k jednotlivým bajtům stuktury jen z důvodu odesílání dat po sériové lince tak klidně mužeš použít pointer na jednotlivá paměťová místa ve struktuře a nekomplikovat si to kombinovaným zápisem struct/union.... a navíc nepíšeš v jakým C/C++ to děláš ale existuje i možnost tzv. Serializace, která ti struktutu převede na sekvenci bytů atd... možností je mnoho..

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:303d:efb1:bbf4:78...–
29. 3. 2021   #4
-
0
-

K jednotlivým prvkům pole se dá dostat pomocí indexu nebo ukazatele. Pole se pak dá zpracovat cyklem. K jednotlivým bitům se pak dá dostat pomocí bitových AND a v případě zpracování celého Byte v cyklu spolu s bitovým posunem vpravo. Na to je vhodné napsat makra.

V případě jednočipu bych si rozmyslel, zda je "atomizace" bitů na hromadu struktur nutná. Paměti a strojového času není nazbyt. V závislosti na rychlosti sběrnice a komunikačním protokolu bych zvážil, zda lze přijatý Byte zpracovat hned při příjmu. Každé procházení pole je cyklus, čím více cyklů tím více času.

Vyhnul bych se implementačně závislým řešením. Pokud děláš pro jednočip a současně i aplikaci pro Windows, narazíš na rozdílné velikosti datových typů. Navíc se může lišit endianita a způsob zarovnávání dat v paměti. Pak chodí data chaoticky. Dva příklady z praxe:

Za použití unionu pro čtení jednotlivých Bytů z int v prostředí Keil 51 bych vraždil. Takový kód v EW 8051 nefunguje kvůli endianitě, jeho úprava stojí hodně práce (pro novější verzi je převodník, ale pro uživatele starších verzí je nedostupný). Při tom stačí použít bitové AND a posun vpravo o 8 bitů a kód se stává implementačně nezávislým. Navíc nemusím dumat nad uspořádáním v paměti. Překladač optimalizuje, sám dobře ví, jakou má endianitu, bitové operace vynechá a do paměti sáhne rovnou pro správný Byte (díval jsem se do výpisu v Assembleru). Tuhle optimalizaci uměl EW 8051 ver. 7.x už před cca 15 lety.

Když v prostředí Atmel studio použiješ union pro long a byte abys long mohl odeslat přes UART, Byty příjdou na přeskáčku.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
Axinox
~ Anonymní uživatel
2 příspěvky
29. 3. 2021   #5
-
0
-

Děkuji za odpovědi. 

Ještě dodání informací. Programuji to v C a jedná se o komunikaci CAN za pomocí přímého přístupů do registru. uC STM32. Ve struktuře právě mám definováno délku dat, ID, data[8] atd.. No a já bych chtěl do těch dat[8] přistupovat třeba takhle msg.data.byte0.bit5 = nějaká hodnota;

Nahlásit jako SPAM
IP: 5.102.63.–
29. 3. 2021   #6
-
+1
-
Zajímavé
Kit +

bit 0 = Byte & 0x01;
bit 1 = (Byte >> 1) & 0x01;

atd. Lze zobecnit jako bit x = = (Byte >> x) & 0x01; Což může vést k zápisu makra

#define BIT_OF_BYTE(byte, bit_position)  ((byte >> bit_position) & 0x01)

Varuji před přístupem

bit 2 = Byte & 0x04;

Pokud bys každý bit považoval za true / false a udělal např. (bit2 & bit4), vždy bys dostal false.

Jinak přístup k jednotlivým bitům jako ke struktuře používá EW 8051 např. u registrů. V hlavičkových souborech jsou pak deklarovány jako union:

__sfr __no_init volatile union
{
  unsigned char PSW; /* Program Status Word */
  struct /* Program Status Word */
  {
    unsigned char P : 1;
    unsigned char F1 : 1;
    unsigned char OV : 1;
    unsigned char RS0 : 1;
    unsigned char RS1 : 1;
    unsigned char F0 : 1;
    unsigned char AC : 1;
    unsigned char CY : 1;
  } PSW_bit;
} @ 0xD0;


hu

Dotatečná pozn.: překladač to musí umět zpracovat do podoby bity v Bytu a umět získávat jednotlivé bity.

Nahlásit jako SPAM
IP: 193.86.81.–
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, 106 hostů

Podobná vlákna

Vnořování prvků — založil Mircosoft

Struct — založil

Dyn Struct — založil myth

Struct vs. class — založil Jakub Sosnovec

Struct vo funkcii — založil Eversmann

Moderátoři diskuze

 

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