Variables ve funkcích
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Variables ve funkcích
Ahoj.
Jsem tu nový, tak na mě budtě hodní.
Mám dotaz, který jsem úplně nevygooglil.
Mám definované nějaké proměnné. Vše mám definované v hlavním programu. Proměnné ve funcích definované nemám, ale pro přehlednost funkce používám.
Jak se to má s přenosem proměnných mezi loopem a funkcí, funkcí a loopem a mezi funkcí a funkcí? Dočetl jsem se, že proměnná ve funkci se dá použít jen v dané funci, ale co když ve funkci používám proměnou definovanou globálně?
Narazil jsem totiž na to, že se některé globální promměné ve funci použít dají a jiné ne a nechápu proč jsou tam ty rodíly.
Například mám několik proměnných s hodnotou. Pak mám funkci "void writeSD()", kterou zavolám "writeSD();"
Uvnitř funkce zapisuji asi tak 10 proměnných na SD. 6 se mě jich zapíše a zbylé 4 mají hodotu 0, ačkoliv v hlavní smyčce loop hodnotu mají. Přitom všechny jsou definované globálně. Nevypozoroval jsem, že by to souviselo s typem té promměné, nebo s tím, zda proměnná dostala hodnotu v loopu, nebo v jiné funkci.
Když si to upravím a promměné vydefinuji při volání funkce např. "writeSD(alt, altKalman, mainFire);" a ve funkci např. "void writeSD(float alt, float altKalman, bool mainFire)" tak už se mě tam hodnota proměnné přenese. Nechápu ale, proč to u některých proměnných funguje i bez.
Principielně bych uvítal, kdyby ty globální proměnné byli vidět prostě všude skrze loop i všechny funkce, ale to nevím zda jde (ačkoliv bych řekl, že některé z těch proměných se tak chovají).
Dále jsem narazil na ještě jedno divné chování, které nevím zda souvisí.
Mám globální proměnnou float, která nabývá v loopu hodnotu příkazem z knihovny.
Konkrétně: float altKalman = pressureKalmanFilter.updateEstimate(alt);
Hned pod tím mám v loopu:
prevAltKalman = altKalman;
Když si následně vypíši obě promměné, tak altKalman má nějakou hodnotu a prevAltKalman má stále hodnotu 0. Nechápu kde je chyba. Obě jsou float, vše se odehrává v loopu.
Přitom hned pod tím mám toto a tam se mě hodota přenese.
if (altKalman > maxAltKalman) {
maxAltKalman = altKalman;
}
Díky.
Jsem tu nový, tak na mě budtě hodní.
Mám dotaz, který jsem úplně nevygooglil.
Mám definované nějaké proměnné. Vše mám definované v hlavním programu. Proměnné ve funcích definované nemám, ale pro přehlednost funkce používám.
Jak se to má s přenosem proměnných mezi loopem a funkcí, funkcí a loopem a mezi funkcí a funkcí? Dočetl jsem se, že proměnná ve funkci se dá použít jen v dané funci, ale co když ve funkci používám proměnou definovanou globálně?
Narazil jsem totiž na to, že se některé globální promměné ve funci použít dají a jiné ne a nechápu proč jsou tam ty rodíly.
Například mám několik proměnných s hodnotou. Pak mám funkci "void writeSD()", kterou zavolám "writeSD();"
Uvnitř funkce zapisuji asi tak 10 proměnných na SD. 6 se mě jich zapíše a zbylé 4 mají hodotu 0, ačkoliv v hlavní smyčce loop hodnotu mají. Přitom všechny jsou definované globálně. Nevypozoroval jsem, že by to souviselo s typem té promměné, nebo s tím, zda proměnná dostala hodnotu v loopu, nebo v jiné funkci.
Když si to upravím a promměné vydefinuji při volání funkce např. "writeSD(alt, altKalman, mainFire);" a ve funkci např. "void writeSD(float alt, float altKalman, bool mainFire)" tak už se mě tam hodnota proměnné přenese. Nechápu ale, proč to u některých proměnných funguje i bez.
Principielně bych uvítal, kdyby ty globální proměnné byli vidět prostě všude skrze loop i všechny funkce, ale to nevím zda jde (ačkoliv bych řekl, že některé z těch proměných se tak chovají).
Dále jsem narazil na ještě jedno divné chování, které nevím zda souvisí.
Mám globální proměnnou float, která nabývá v loopu hodnotu příkazem z knihovny.
Konkrétně: float altKalman = pressureKalmanFilter.updateEstimate(alt);
Hned pod tím mám v loopu:
prevAltKalman = altKalman;
Když si následně vypíši obě promměné, tak altKalman má nějakou hodnotu a prevAltKalman má stále hodnotu 0. Nechápu kde je chyba. Obě jsou float, vše se odehrává v loopu.
Přitom hned pod tím mám toto a tam se mě hodota přenese.
if (altKalman > maxAltKalman) {
maxAltKalman = altKalman;
}
Díky.
Re: Variables ve funkcích
Možná si odpovím sám na druhou část.
Když mám definouvanou globální proměnnou:
float altKalman;
a pak v loopu:
float altKalman = pressureKalmanFilter.updateEstimate(alt);
Tak to je nově definovaná promměná ke které není z vnitřku funkcí přístup?
Je zajímavé, že v loopu samotném pak zřejmě náhodně dochází někdy k použití té globální a někdy té druhé.
Když mám definouvanou globální proměnnou:
float altKalman;
a pak v loopu:
float altKalman = pressureKalmanFilter.updateEstimate(alt);
Tak to je nově definovaná promměná ke které není z vnitřku funkcí přístup?
Je zajímavé, že v loopu samotném pak zřejmě náhodně dochází někdy k použití té globální a někdy té druhé.
- pavel1tu
- Příspěvky: 2054
- Registrován: 26 říj 2017, 08:28
- Reputation: 0
- Bydliště: Trutnov
- Kontaktovat uživatele:
Re: Variables ve funkcích
Dej sem celý zdroják pomocí "zobrazení kodu"
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"
Pavel1TU
"Správně napsaný kod lze číst jako knihu"
Re: Variables ve funkcích
Když máš stejný název, tak do bude dělat, ale když dáš do loop1 a loop2 stejný název, tak to nebude vadit.
- pavel1tu
- Příspěvky: 2054
- Registrován: 26 říj 2017, 08:28
- Reputation: 0
- Bydliště: Trutnov
- Kontaktovat uživatele:
Re: Variables ve funkcích
Testnul jsem to,
ne tedy se zápisem na SD,
ale třeba zápisem do EEPROM,
odeslání po 485,
odeslání na WEB.
Já dělám skoro vše funkcemi, ty pak využívám i v jiných projektech,
vždy definuji proměnné globálně,
nikdy mi to neudělalo co zmiňuješ.
Nedělá to knihovna k SD kartě ?
Nedělají to jen proměnné nějakého typu ?
Nemají ty proměnné název který koliduje s nějakou knihovnou nebo něčím ? (já proto proměnné pojmenovávám "cecky", tedy jako česky)
Musí v tom být logika přeci .... podle čeho to kompilátor zkompiluje a poté to nefunguje.
ne tedy se zápisem na SD,
ale třeba zápisem do EEPROM,
odeslání po 485,
odeslání na WEB.
Já dělám skoro vše funkcemi, ty pak využívám i v jiných projektech,
vždy definuji proměnné globálně,
nikdy mi to neudělalo co zmiňuješ.
Nedělá to knihovna k SD kartě ?
Nedělají to jen proměnné nějakého typu ?
Nemají ty proměnné název který koliduje s nějakou knihovnou nebo něčím ? (já proto proměnné pojmenovávám "cecky", tedy jako česky)
Musí v tom být logika přeci .... podle čeho to kompilátor zkompiluje a poté to nefunguje.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"
Pavel1TU
"Správně napsaný kod lze číst jako knihu"
Re: Variables ve funkcích
Klucí testnu to večer doma. Teď nemám u sebe.
Zatím mám pracovní teorii, že jsem tímto nadefinoval jednu globální proměnou a druhou v loopu stejného názvu. Přičemž funkce si šáhne na tu globální a i v loopu se to chovalo divně. Udělal jsem si teď jen test v simulátoru a chová se to přesně tak.
Zatím mám pracovní teorii, že jsem tímto nadefinoval jednu globální proměnou a druhou v loopu stejného názvu. Přičemž funkce si šáhne na tu globální a i v loopu se to chovalo divně. Udělal jsem si teď jen test v simulátoru a chová se to přesně tak.
Kód: Vybrat vše
float test=0;
void setup() {
Serial.begin(9600);
void loop() {
Serial.println(test);
Serial.println("Test z loopu");
delay(1000);
float test=1;
Serial.println(test);
Serial.println("Test z loopu");
delay(1000);
funkce();
}
void funkce() {
Serial.print(test);
Serial.println("Test z funkce");
delay(1000);
}
Re: Variables ve funkcích
Je potřeba si uvědomit, že loop a setup jsou taky funkce. Pokud v nich deklaruješ proměnnou, bude dostupná pouze v rámci oné funkce.
Kód: Vybrat vše
int a = 1; // tato proměnná je globální a bude dostupná z jakékoliv funkce
void setup() {
int b = 1; // tato proměnná je lokální a bude dostupná pouze v rámci setup
Serial.begin(9600);
}
void loop() {
ínt c = 1 // tato proměnná je lokální a bude dostupná pouze v rámci loop
Serial.println(a); // dostaneš 1 (je to globální proměnná)
Serial.println(b); // dostaneš 0 (protože v této funkci není proměnná b definována)
Serial.println(c); // dostaneš 1 (lokální proměnná dostupný v loopu)
vypisABC();
}
void vypisABC(){
Serial.println(a); // dostaneš 1 (je to globální proměnná)
Serial.println(b); // dostaneš 0 (protože v této funkci není proměnná b definována)
Serial.println(c); // dostaneš 0 (protože v této funkci není proměnná c definována)
}
Re: Variables ve funkcích
Je to celkem jednoduche:
- promenna definovana uvnitr funkce (scopu) je viditelna jen uvnitr funkce scopu), po skonceni funkce scopu) zanika, pri zavolani funkce (scopu)je zalozena nova.
- promenna definovana globalne je viditelna globalne, vznika pri startu programu, zanika pri jeho ukonceni (u arduina tedy nikdy)
- promenna definovana uvnitr funkce prekryje promennou definovanou globalne (tedy pri pouziti toho jmena se mysli promenna z nejblizsi oblasti (funkce)
- setup() i loop() jsou funkce, takze to na ne plati taky
- slozene zavorky a cykly jsou scoop, takze to na ne plati taky
Kód: Vybrat vše
int glob; //globalni promenna
int i=1; //globalni i
nastav (){
int loc; // lokalni v nastav
loc=i; // priradim hodnotu globalniho i, tedy 1
glob=loc; // loc lokalni v nastav, nastavene na 1 z globalniho i
}
setup(){
int loc; // lokalni v setupu - nijak nesouvisi s s loc z nastav, a naopak
int i=2; //lokalni v setup, nesouvisi s globalnim i
loc=i; // pouziju lokalni i, tedy 2
for (int i=10;i<=20;i++) { // lokalni ve for, nesouvisi ani s globalnim i, ani s i lokalnim v setupu
loc=i; // prirazuju i z for ..., tedy 10..20
{
int i=40; //lokalni v techto zazvorkach
loc=i; // loc lokalni v setup, i lokalni v zavorkach, priradim 40, vzdy
nastav(); // v nastav se do jeho lokalni loc nastavi globalni i, tedy 1
// glob je nastavene na 1
glob=loc; // tady se pouzije loc lokalni v setupu, do ktere je prirazena 40 z i lokalniho v techto zavorkach
};
glob=loc; // tady se pouzije loc lokalni v setupu, do ktere je prirazena 40 z i v zavorkach, ktere ale uz neni
loc=i; // prirazuju i z for ..., tedy 10..20
glob=loc; // tady se pouzije loc lokalni v setupu, do ktere je prirazena 10..20 z i lokalniho ve for
}; /// konec for
loc=i; // pouziju lokalni i, tedy 2
glob=loc; // tady se pouzije loc lokalni v setupu, do ktere je prirazena 2 z i lokalniho v setupu
pinMode(10,INPUT); //pin 10 je pro cteni
}
loop(){
int loc; //lokalni v loop
int i=99; // lokalni v loop
Serial.print(glob); // glob je v prvnim pruchodu nastavene ze setup na 2, v dalsich pruchodech na je 0 nebo 1, podle tlacitka v minulem pruchodu
loc=i; // lokalni i v loop je 99
nastav(); // glob nastavi na 1 (z globalniho i)
Serial.print(glob); // glob je nastavene na 1 z nastav()
glob=loc; // nastavene z lokalniho loc, nastaveneho z lokalniho i na 99
Serial.print(glob); // glob je nastavene na 99
glob=digitalRead(10); // bud 1, nebo 0 podle tlacitka
Serial.print(glob); // glob je nastavene na 0 nebo 1podle tlacitka pred chvili v tomto pruchodu
}
Re: Variables ve funkcích
IMHO dostanes chybu prekladace (neznama prommenna b), protoze promenna b NENI dostupna v tomto miste, obdobne v dalsi funkci b a ckiRRow píše: ↑19 zář 2019, 16:28Je potřeba si uvědomit, že loop a setup jsou taky funkce. Pokud v nich deklaruješ proměnnou, bude dostupná pouze v rámci oné funkce.
Kód: Vybrat vše
void loop() { ínt c = 1 // tato proměnná je lokální a bude dostupná pouze v rámci loop Serial.println(a); // dostaneš 1 (je to globální proměnná) Serial.println(b); // dostaneš 0 (protože v této funkci není proměnná b definována)
Re: Variables ve funkcích
První chybu dostaneš hned za loopem, protože mi tam chybí středníkgilhad píše: ↑19 zář 2019, 16:39IMHO dostanes chybu prekladace (neznama prommenna b), protoze promenna b NENI dostupna v tomto miste, obdobne v dalsi funkci b a ckiRRow píše: ↑19 zář 2019, 16:28Je potřeba si uvědomit, že loop a setup jsou taky funkce. Pokud v nich deklaruješ proměnnou, bude dostupná pouze v rámci oné funkce.
Kód: Vybrat vše
void loop() { ínt c = 1 // tato proměnná je lokální a bude dostupná pouze v rámci loop Serial.println(a); // dostaneš 1 (je to globální proměnná) Serial.println(b); // dostaneš 0 (protože v této funkci není proměnná b definována)
Neslouží to ke kompilaci, ale jen k ukázce toho jak se chovají ty proměnné.
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 39 hostů