forum.mcontrollers.com - hlavní stránka forum.mcontrollers.com - fórum

 

.: fórum - hlavní stránka :.
Technology Stronghold by Rudolf Vesely
How to build Microsoft System Center hosted cloud series
FAQFAQ HledatHledat Seznam uživatelůSeznam uživatelů Uživatelské skupinyUživatelské skupiny RegistraceRegistrace
ProfilProfil StatistikaStatistika Soukromé zprávySoukromé zprávy PřihlášeníPřihlášení

 
Práce se strukturami v C

 
Přidat nové téma   Zaslat odpověď    Obsah fóra mcontrollers.com -> Jiné mikrokontroléry, procesory, hradla
 
piityy
Profesionál
Profesionál


Založen: 1.4.2008
Příspěvky: 2139

PříspěvekZaslal: 10 březen 2011, 3:13    Předmět: Práce se strukturami v C Citovat

Zdarec,
dnes jsem byl opět nemile překvapen.
Mějme strukturu s deklarací a definicí níže:
kód:
typedef struct
{
   unsigned char SS;
   unsigned char MM;
   unsigned char HH;
   unsigned char updated;   // true when struct changed in interrupt
}time_t;

volatile time_t cas; // global

Dále funkci a její volání:
kód:
void casNaText(time_t tData, char *tstr)
{
   // ...
   tData.updated = FALSE;
}

casNaText(cas, casText);

Toto nefunguje. Z proměnné (typu struktura, volatile) mohu pouze číst, změna se na původních datech neprojeví. Žil jsem doteď v desiluzi, že struktura je referenční datový typ a tedy stejně jako u pole se manipulace v ní projeví na původních datech. Očividně ne a celá struktura se patrně kopíruje jako primitivní datový typ.

Pokud to přepíšu na pointery, pracuje to správně ovšem s varováním o ztraceném kvalifikátoru (určitě volatile):
kód:
void casNaText(time_t *tData, char *tstr)
{
   // ...
   (*tData).updated = FALSE; // funguje oboji
   tData->updated = FALSE;
}

casNaText(&cas, casText);

Vím, že už jsem na to narazil(a jako dnes to vyřešil pointerem), ale teprve dnes jsem se nad tím nějak pozastavil.
Mohl by mi to někdo lehce osvětlit? Onu legendární knížku o C bohužel nevlastním Sad.

Druhá věc: lze zařídit přenos "volatile" i do funkce?

Arrow administrator: přesunuto z "Ostatní"
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

 
jaromir
Profesionál
Profesionál


Založen: 11.12.2009
Příspěvky: 193
Bydliště: Bratislava

PříspěvekZaslal: 10 březen 2011, 9:11    Předmět: Citovat

No mne to pride ako normalne chovanie.
Ked urobis toto

kód:

void casNaText(time_t tData, char *tstr)
{
   tData.updated = FALSE;
}
casNaText(cas, casText);


Tak do funkcie natlacis dve premenne (nech su akekolvek, aj char alebo float), upravis ich a nikde nevratis - teda kompilator by urobil chybu ak by upravoval originalne data, pretoze si mu nikde nepovedal, aby tak urobil. Volanie funkcie s parametrami znamena vytvorenie novych premennych na stacku a tie sa upravuju, pripadne sa presuvaju na odovzdanie. Ak sa neupravuju, tak opustenim funkcie su nenavratne stratene a kompilator by ich mal podla spravnosti odoptimalizovat.

Jednou z moznosti ako tu urobit je to, ze ak si uz zadefinujes globalnu premennu, tak ju nedavat do parametrov, ale upravovat ju priamo, ako globalnu premennu. Cistejsie riesenie (co do programatorskej moralky) je urobit to cez pointery alebo urobit navratovy typ funkcie na time_t a returnovat tData.

_________________
Moje osobne stranky: http://jaromir.xf.cz/ - aktualizacia 11.8, pridana stranka okolo BSD Unixu na PIC32
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
 

 
piityy
Profesionál
Profesionál


Založen: 1.4.2008
Příspěvky: 2139

PříspěvekZaslal: 10 březen 2011, 13:19    Předmět: Citovat

Mě to tak úplně normální nepřišlo. Jméno struktury (nevím, kde jsem k tomu přišel) jsem pokládal za odkaz(= ptr) na její začátek (jako u pole). Očekával jsem tady chování pro takový objekt běžné.
Jeden zdejší kolega mě odkázal na písmo svaté a struktury se od ANSI C opravdu předávají hodnotou, pro odkaz je nutný pointer.

Teď jdu ještě zkoumat, jesli tam nenajdu něco o volatile parametru funkce.
Edit: O předávání volatile jsem se nedočet, ale snad stačí trochu přemejšlet.
Jelikož v C neexistuje volání odkazem, volá se vždy hodnotou. Pokud je parametrem funkce pointer, předá se jeho hodnota (adresa na kterou ukazuje). Pokud však jsou cílová data volatile, tak v tom stavu zůstávají, typový modifikátor chybí pouze u onoho pointeru. To má nejspíš následky, že pokud se během funkce změní původní předávaný pointer, tak míří jinam, než ten do funkce předaný. Důsledek bude, že pokud původní data zmizela (jsou neplatná), funkce bude pracovat s nesmysly. Zůstanou_li však cílová data na místě a jen se změní, funkce bude mít stále data aktuální.
Potřeboval-li bych mít volatile i předávaný pointer (např. u dynamicky alokovaných prvků), bylo by nutné vytvořit pointer na pointer jako parametr funkce a v ní se dle toho zařídit.
Nádhera Smile.
Z předchozího příkladu (struktura není dynamická) je tedy vhodný tento zápis (bez varování):
kód:
casNaText((time_t *)(&cas), casText);
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

Zobrazit příspěvky z předchozích:   
Zobrazit předchozí téma :: Zobrazit následující téma  
Přidat nové téma   Zaslat odpověď    Obsah fóra mcontrollers.com -> Jiné mikrokontroléry, procesory, hradla Časy uváděny v GMT + 2 hodiny
 
Strana 1 z 1
Přejdi na:  
Můžete přidat nové téma do tohoto fóra.
Můžete odpovídat na témata v tomto fóru.
Nemůžete upravovat své příspěvky v tomto fóru.
Nemůžete mazat své příspěvky v tomto fóru.
Nemůžete hlasovat v tomto fóru.
Můžete k příspěvkům připojovat soubory
Můžete stahovat a prohlížet přiložené soubory
 



Num Lock Holder - app to hold Numlock
Copyright © 2018 Rudolf Veselý, mcontrollers.com.
Je zakázáno používat části tohoto webu bez souhlasu autora. || Powered by phpBB © 2001, 2002 phpBB Group - with RedSquare DoubleJ(Jan Jaap)