Funkce a přebírání hodnot do jiných funkcí – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Funkce a přebírání hodnot do jiných funkcí – C / C++ – Fórum – Programujte.comFunkce a přebírání hodnot do jiných funkcí – C / C++ – Fórum – Programujte.com

 

kuba7480
Duch
26. 11. 2017   #1
-
0
-

Dobrý den,

chtěl bych se zeptat, zda-li  můžu nějak v C použít průběžný výsledek z určité funkce v jiné funkci a případně, jak se k němu můžu dostat.

Děkuji všem za rady!

Nahlásit jako SPAM
IP: 90.181.37.–
MilanL+1
Grafoman
28. 11. 2017   #2
-
0
-

#1 kuba748
jde o to jak to myslíš je několik možností, jak programy běží a to má vliv jak potom fungují běhy funkcí:

1) konzolový program - klasický : jede pouze 1 programové vlákno - při volání funkce se čeká na její dokončení a pak se teprve pokračuje

2) konzolový program - s vlákny : Hlavní programové vlákno + několik funkčních vláken - u vlákna možno vytvořit funkci vracející stav, po aktivaci funkce ve vlákně může nadřízená část programu pokračovat a na dokončení vlákna počkat až ve chvíli, kdy potřebuje její výsledek.

3) událostmi řízený program : Hlavní programové(aplikační) vlákno + obsluha událostí [+ funkční vlákna]  - mezivýsledek možno získat obdobně jako u 2) funkcí nebo událostí vracející stav objektu. Hlavní vlákno sleduje vstupy (klávesnice, myš apod) na jejich základě pak určuje objekt a událost která se má obsloužit.

Přístup k mezivýsledku tedy závisí na konkrétní situaci.

Nahlásit jako SPAM
IP: 91.139.9.–
peter
~ Anonymní uživatel
3981 příspěvků
28. 11. 2017   #3
-
0
-

Zkus pridat kod prikladu, jak si to treba predstavujes. Viz Milan, je nekolk moznosti

- Proces bezi na pozadi a ceka na data, meni data.
Napr. proces pro vykreslovani kurzoru mysi. mysi nehybes, nic nedala. Mysi pohnes, smaze kurzor a vykresli na jinem miste. Neustale bezi na pozadi a ceka na data od mysi.

- Program s jednim vlaknem.
To je treba kopirovani souboru. Spustis, on neco dela a pak se ukonci.

- Program s vice vlakny.
Spustis, on si spusti vice vlaken, programu naraz a pak ceka, az se posledni z nich ukonci. Kazde vlakno si pracuje se svymi promennymi.

A ted nevim, co si predstavujes. Mas asi ceckovou funkci, ktera trva trba 2 min a chce vykreslovat prubeh, treba 0-100%, ne? Tak ta funkce bude ukladat do nejake globalni promenne svuj stav a casova funkce bude stav zobrazovat. Neco jako kurzor mysi, casova funkce ceka na souradnice a vykresli novy kurzor.
Nebo muzes zobrazovani zabudovat primo do funkce.

http://programujte.com/forum/vlakno/10861-globalni-promenne/
http://www.builder.cz/…idy-155677cz

Nahlásit jako SPAM
IP: 2001:718:2601:258:c4ce:4c...–
JerryM0
Věrný člen
28. 11. 2017   #4
-
0
-

#1 kuba748
pokud nepoužíváš vlákna mužeš použít buď globální proměnou nebo proměnou typu AUTO v dané funkci nebo memory stream

https://linux.die.net/man/3/open_memstream

pokud používáš vlákna tak to samý :))) ale potřebuješ (asi nejspíš možná - záleží na konkrétním příkladu)  k tomu synchronizační mechanismus (třeba semafory apod. ) jinak se ti budou sem tam vracet blbosti ...

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:e8bd:...–
Staon0
Návštěvník
23. 12. 2017   #5
-
0
-

#1 kuba748
Hmm, nějak mám pocit, že skoro všechny odpovědi míří jinam, než byla položená otázka. Tak to zkusím ještě jednou po svém.

Odpověď zní: ne, není možné se dostat z jedné funkce k proměnné deklarované uvnitř jiné funkce. C ani C++ toto neumožňují a je to jednoznačně správně.

Takže, co dělat, pokud potřebujete mezivýsledek z funkce A do funkce B?

  1. Jediný obecně správný a čistý přístup je si mezivýsledek předat jako argument nebo jako návratovou hodnotu.
  2. Funkce A může mezivýsledek uložit do globální proměnné - to je proměnná deklarovaná mimo jakoukoliv funkci a B k ní může přistoupit.
  3. Funkci B se jako argument předá ukazatel na proměnnou ve funkci A. B pak pomocí dereference (operátor *) může číst její hodnotu. Zde je kromě dalších problémů potřeba počítat s tím, proměnná ve funkci A, pokud není statická, existuje pouze v době, kdy A je vyvolaná (tzn. B by musela být (transitivně) vyvolaná z A).

Varianta 2 a varianta 3 s odkazem na statickou proměnnou jsou téměř jednoznačně špatné: zavádí příliš těsnou vazbu mezi funkcemi, takže změna implementace je náročná a vzniká neudržitelný kód. Zároveň, jak tu bylo zmíněno, přináší problémy se synchronizací ve vícevláknovém prostředí. Něco takového je prostě známkou špatného návrhu. Přesto se někdy používají, obvykle z důvodů výkonnostní optimalizace.

Varianta 3 s odkazem na auto proměnnou se naopak používá poměrně hodně. Pokud z funkce A provolám (nemusím nutně přímo) funkci B, pak předáním ukazatele zabráním kopírování mezivýsledku (předávám malý ukazatel). Takže to vlastně funguje jako varianta 1, ale data se nekopírují. V tomto případě je dobrým zvykem předávat ukazatel na konstantu. Platí to ovšem pro variantu, kdy si data předáváte jako argument dolů, nejde to použít pro předání návratové hodnoty nahoru, protože automatická proměnná se s koncem funkce zruší.

Nahlásit jako SPAM
IP: 94.112.135.–
Jerry
~ Anonymní uživatel
504 příspěvků
23. 12. 2017   #6
-
0
-

#5 Staon
hezky si to napsal ... to je přesně to co sem ti popsal v mojí předchozí odpovědi .. takže pořád nějak nechápu co vlastně chceš :))))

eště si zapomněl na sdílenou paměť mezi funkce to by byl bod 4. víííííš pupíčku :) ale to se týká hlavně jazyka C v C++ se to dělá blbě a musíš na to napsat tzv .wrapper....

odpověď zní jednoznačně ANO, protože v céčku si můžeš vložit kod assembleru na rezerovvanou část paměti a pak tuto "proměnnou" sdílet ve více funkcích .. tak že ANO dá se dostat z funkce A k proměnné ve funkci B .. to se ti tu snaží všichni vysvětlit ... a ty pořád nic.. .oni ti to ve škole neřekli ??? božeee....

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:53d:1...–
Jerry
~ Anonymní uživatel
504 příspěvků
23. 12. 2017   #7
-
0
-

#6 Jerry
jo a taková paměť --- rozuměj sdílená proměnná NENI známkou špatného návrhu jen jde o to, že musíš ještě doplnit nějaký synchro prvek do té oblasti paměti, dělá se to běžně na nižších urovních těsně nad assemblerem a pak také při přístupu k videopaměti ale ty o tom nevíš protože ve syšších prog. jaz se na tohle už nenarazí ..

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:53d:1...–
Staon0
Návštěvník
23. 12. 2017   #8
-
0
-

#6 Jerry
Hele Pupíčku, nějak jsem si nevšiml, že bychom spolu někdy pásli krávy, takže možná bys mohl tomuto faktu uzpůsobit svoje vyjadřování. Jinak tvoje reakce dost nápadně připomíná pořekadlo o potrefené huse...

Abych shrnul, proč jsem přidal svou odpověď. Zaprvé, otázka byla položená ve vlákně C/C++. Ne ve vlákně assembler. Zadruhé, otázka byla jak předávat data mezi funkcemi. Nezněla jak předávat data mezi procesy, ani jak mezi vlákny. Z tohoto pohledu skoro všechny odpovědi odpovídají na jinou otázku. Jediná, která se částečně trefila je ta tvoje. Bohužel ze tří uváděných věcí pouze jedna dává smysl:

  • globální proměnná - to je ta jediná smysluplná,
  • auto proměnná - totální blbost. Automatické proměnné vznikají a zanikají v runtime. Není možné pro ně vytvořit linkovací symbol, a proto není možné k nim přistoupit mimo jejich scope. Jediná možnost je na ně předávat ukazatel v callstacku dolu, což je moje varianta 3 - přes veškerou snahu nemůžu v tvém příspěvku najít, že bys něco takového zmiňoval.
  • Streamy, sdílené paměti - to jsou techniky pro meziprocesovou komunikaci. Řekni mi jediný jejich přínos pro předávání dat mezi funkcemi (význam nemají ani mezi vlákny)!

Globální proměnné jsou vždy známka špatného návrhu. Způsobují příliš těsnou vazbu a vzniká tak nerozšiřitelný, na vlákna nebezpečný a extrémně netestovatelný kód. A pokud se rozhodneš použít globální proměnnou pro předávání dat mezi funkcemi (tzn. zhoršit návrh), tak už k tomu musíš mít sakra dobré důvody. Bože, to tě ve škole nic nenaučili? Možná ano, ale byla to promarněná energie, protože embedáři jsou skálopevně přesvědčení, že pro ně žádná pravidla programování neplatí.

Nahlásit jako SPAM
IP: 94.112.135.–
Jerry
~ Anonymní uživatel
504 příspěvků
23. 12. 2017   #9
-
0
-

#8 Staon
nechápu proč bys nemoch bejt pupíček :))) sou přeci vánoce ne ?

....a třeba v C++/CLI nebo v C++/CX vubec žádný globální proměnný jako v C a C/C++ neexistujou, existujou jenom statický kontruktory objektů a statický proměnný (tedy typ AUTO z céčka)... takže jak vidíš můžeš používat všechno co tě napadne.... protože až to překladač přeloží do assembleru stejně nikdo nepozná co tam bylo ... nicméně kuba748 se ptal jestli může využít průběžný výsledek jedné funkce v jiné funkci to ale buď předpokládá, že se jedná o vícevláknový proces nebo je tam přidaná nějaká callback funkce... v obou případech se dá využít vše výše jemnované ...

ať žijou pupíčci :))

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:b8d7:...–
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, 11 hostů

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ý