Lokalna premenna - ujasnenie

C,C++,C#

Moderátori: psichac, Moderátori

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4418
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Lokalna premenna - ujasnenie

Príspevok od používateľa romiadam » 26 Sep 2022, 11:56

Ahojte,
Viem ze ak pred main() deklarujem premennu, tak je to globalna premenna.
A ked premennu deklarujem vo vnutri nejakej funkcie tak je lokalna premenna pre tu funkciu a ona "umrie" akonahle program opusti tu funkciu kde bola deklarovana.

Otazka1: Tato lokalna premenna c (vid priklad nizsie)deklarovana vo funkcii Vypocet(), je platna aj v dalsich volanych funkciach?
(Pozn. Nehladajte v tom logiku, je to len ilustracia co mam na mysli.)

Kód: Vybrať všetko

int a;
int b;
int vysledok;
main()
{
vysledok = Vypocet();
}

int Vypocet()
{
int c;
int d;
c=a+b	// a, b, su glob. premenne - zname
d = Delenie();
return (c+d);
}

int Delenie()
{
return=c/2;		// c je lokalna prenmenna deklarovana vo Vypocet(). Je znama aj tu? 
				//Popr. ak by sa zavolala dalsia funkcia, je znama aj tam?
}

Bez ohladu na to ci sa to robi takto alebo nie (toto je len priklad ci chapem lok. premennu), fungoval by ten priklad?



Otazka 2:
Mozem aj takto vytvorit blok a v nom lokalnu premennu len pre konkretny vypocet? Potrebujem "podrzat" na chvilku privypoctoch nejaky medzi vysledok
(Pozn. Nehladajte v tom logiku, je to len ilustracia co mam na mysli.)

Kód: Vybrať všetko

int  a;
main()
{
	prikaz;
	prikaz;
		{
		int c;
		c= a/3;
		a= c+5;
		}
	prikaz;
	prikaz;	
}
Toto vyssie by fungovalo alebo nie?
0
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2574
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: Lokalna premenna - ujasnenie

Príspevok od používateľa maskrtnik01 » 26 Sep 2022, 12:07

Otázka 1: Premenná deklarovaná v rámci nejakej funkcie je platná iba v danej funkcii. Ak chcete jej hodnotu použiť v ďalšej funkcii, je možné ju predať ako parameter. Ak ju chcete vnútri volanej funkcie zmeniť tak, aby sa zmena prejavila vo volajúcej funkcii, je možné predať pointer na premennú ako parameter.

Otázka 2: Tak o tomto som vôbec nevedel. Takúto deklaráciu premennej som v živote nepoužil, ale skutočne je možné deklarovať premennú v bloku kódu, a mimo tento blok nebude platná. V ďalšom bloku môže byť deklarovaná premenná s rovnakým názvom.

Moja otázka: Syntakticky je deklarácia z otázky 2 možná a bude fungovať. Avšak z hľadiska prehľadnosti, je toto prínosom, alebo naopak?
0

Atlan
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1148
Dátum registrácie: 01 Feb 2008, 00:00
Bydlisko: Kosice okolie

Re: Lokalna premenna - ujasnenie

Príspevok od používateľa Atlan » 26 Sep 2022, 12:41

Premena c takto fungovat nebude a kedy si to hodil to prekadaca vyhodi chybu. Lebo v f7nkcii delenie nieje deklarovana
0

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4418
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Re: Lokalna premenna - ujasnenie

Príspevok od používateľa romiadam » 26 Sep 2022, 15:36

Aha, takze napriek tomu ze c je deklarovane vo Vypocet() a Delenie() je volane z Vypocet(), to neznamena ze c bude existovat aj v Delenie() .
Zaujimave. Ja som si myslel ze bude existovat vo vsetkych volanych funkciach.


A co ten blok? (Otazka 2). To by mohlo tak byt?
0
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

maskrtnik01
Ultimate člen
Ultimate člen
Príspevky: 2574
Dátum registrácie: 20 Júl 2010, 00:00
Bydlisko: okolie KE
Vek: 27

Re: Lokalna premenna - ujasnenie

Príspevok od používateľa maskrtnik01 » 26 Sep 2022, 15:44

Nikdy som to nepoužil, myslím že je to aj neprehľadné. Ale overil som si to, dá sa to.
0

Používateľov profilový obrázok
Andy99
Stály člen
Stály člen
Príspevky: 339
Dátum registrácie: 05 Mar 2008, 00:00
Bydlisko: BA
Vek: 35

Re: Lokalna premenna - ujasnenie

Príspevok od používateľa Andy99 » 26 Sep 2022, 15:46

Otazka 2: Bud to fungovat, syntakticky je to spravne, ale neodporucal by som toto riesenie. (Mozes si tym narobit viac problemov, ako osohu.) Skor sa to pouziva s blokom with, ktory, ale nie je v C k dispozicii.

Mozno som nepochopil kontext, ale pokial chces setrit pamat a pouzivat lokalne premenne v inych funkciach, sluzia to pointre a referencie ako parametre funkcie.
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: Lokalna premenna - ujasnenie

Príspevok od používateľa peterple » 26 Sep 2022, 19:54

Už to tu bolo viac menej zopovedané. K bodu dva len malé doplnenie. Samozrejme že sa to používa. Že sa to niekomu javí ako neprehľadné je jeho vec.

Úplne bežne sa to používa napríklad aj takto

Kód: Vybrať všetko

  int i= 10;

	for (int i=0; i<100; i++)
	{
		 printf("%d\n", i);
	}
Premená i v cykle sa vytvorí nová lokálna a zatieni aj tú predtým vytvorenú premennú (lokálnu či globálnu). Teda v cykle mi ide i od jedna po sto. Ale ked cyklus skončí tá vnútorná premenná i zanikne a tá nad tým i sa znova objaví a bude mať hodnotu 10.

C je prechádzka mínovým poľom a kto nie je pyrotechnik si ľahko na nejakú tú mínu nabehne.

Na podobné pokusy je dobré si nainštaľovať C na PC s poriadnym IDE kde je aj solidny debuuger a potom krokovať sa sledovať ako to všetko funguje, krok za krokom.
Pre jednočipy sa dá použiť simulátor.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

Používateľov profilový obrázok
balu
Pokročilý člen
Pokročilý člen
Príspevky: 540
Dátum registrácie: 21 Feb 2022, 12:06

Re: Lokalna premenna - ujasnenie

Príspevok od používateľa balu » 26 Sep 2022, 23:28

peterple napísal:Úplne bežne sa to používa napríklad aj takto


Kód: Vybrať všetko

 int i= 10;

	for (int i=0; i<100; i++)
	{
		 printf("%d\n", i);
	}
Použít to takhle jde, ale běžně se to přímo takhle nepoužívá (tedy myslím definování stejných proměnných v rámci jedné funkce) - ztrácíš tak přehled.

Toto se skutečně používá :

Kód: Vybrať všetko

	for (int i=0; i<100; i++)
	{
		 printf("%d\n", i);
	}
I když místo proměnné i se používá (třeba) Idx. Celé to pak vypadá takto :

Kód: Vybrať všetko

	for (int Idx=0; Idx<100; Idx++)
	{
		 printf("%d\n", Idx);
	}

Použití jednopísmenných (nebo obecně krátkých) proměnných je dobré se vyhybat, stejně tak jako je dobré se vyhybat proměnným s nic neříkajícím názvem (pomocna1, pomocna2, ... pomocna9 atd.). Cčko rozlišuje malá a velká písmena, takže tahle_promenna není Tahle_promenna. Tohle je věc, kterou v žádném případě nedělej - používat dvě různé proměnné rozlišené jenom velikostí písmen.

Je rozdíl mít proměnné s názvem DP, PP nebo DelkaPulzu, PocetPulzu. Proměnné, konstanty atd. by měly dávat smysl. To jediné přispívá k přehlednosti kódu. A když pak dodržuješ formát názvů, tak na první pohled do programu vidíš, jestli jde o lokální/globální proměnnou, IO pin nebo konstantu.

Stejně tak je dobré vyhybat se psaní čísel, týkajících se třeba rozměrů polí (ale třeba i nějakých konstant apod.) přímo do kódu. Takže místo deklarace a použití pole takto :

Kód: Vybrať všetko

int PolePrvku[10];

void NastavPole( void )
{
    for ( int Idx = 0 ; Idx < 10 ; Idx++ )
    {
        PolePrvku[Idx] = 10;
    }
}
je mnohem lepší místo čísla 10 použít definovanou konstantu :

Kód: Vybrať všetko

#define POCET_PRVKU 10
int PolePrvku[POCET_PRVKU];

void NastavPole( void )
{
    for ( int Idx = 0 ; Idx < POCET_PRVKU ; Idx++ )
    {
        PolePrvku[Idx] = 10;
    }
}
ideálně pak :

Kód: Vybrať všetko

#define POCET_PRVKU 10
#define VYCHOZI_HODNOTA 10
int PolePrvku[POCET_PRVKU];

void NastavPole( void )
{
    for ( int Idx = 0 ; Idx < POCET_PRVKU ; Idx++ )
    {
        PolePrvku[Idx] = VYCHOZI_HODNOTA;
    }
}
Tím se pro změnu vyvaruješ chyb, když pak chceš změnit rozměr pole tím, že :
  1. Nespleteš si dvě stejná čísla, která v programu mají různý význam (která 10 je ta správná ?)
  2. Na žádné místo, které potřebuješ změnit nezapomeneš
Ale vraťme se k lokálním/globálním proměnným.

Lokální proměnná (obecně) je proměnná, která je nadefinovaná mezi složenými závorkami { } a je jedno, jestli unvnitř cyklu, funkce nebo bloku.

Pokud potřebuješ, aby lokální proměnná v nějaké funkci byla k dispozici pouze této funkci, ale neztrácela svou hodnotu, může tak být nadeklarována. Například použití jako čítače nebo pro rozfázování nějakého procesu.. Taková proměnná se pak deklaruje jako lokální (tedy uvnitř funkce), ale s příznakem "static" :

Kód: Vybrať všetko

void BlikejLedkou( void )
{
  static int _Krok = 0;

  switch ( _Krok )
  {
    case 1: LedZelenaOut = SVITI;       // Rozsvítit LED
            LedTimer = T_500MS;         // Nastavit časovač na 500ms
            _Krok++;                    // Do dalšího kroku
            break;

    case 2: if ( !LedTimer ) _Krok++;   // Pokud časovač dopočítal, jdi do dalšího kroku
            break;

    case 3: LedZelenaOut = NESVITI;     // Zhasnout LED
            LedTimer = T_500MS;         // Nastavit časovač na 500ms
            _Krok++;                    // Do dalšího kroku
            break;

    case 4: if ( !LedTimer ) _Krok = 1; // Pokud časovač dopočítal, jdi do prvního kroku
            break;

    default: _Krok=1;  // Tohle snad vysvětlovat nemusím ...
             break;
  }
}

Poznámka :
_Krok - lokální proměnná
LedZelenaOut - je to proměnná, která označuje IO pin, kde je zelená LEDka připojená (to znamená to Out na konci)
LedTimer - globální proměnná
SVITI, NESVITI, T_500MS - nadefinované konstanty

Lokální proměnná s příznakem "static" se chová jako lokální, ale má trvale přidělenou paměť stejně, jakoby to byla globální proměnná.
0
Naposledy upravil/-a balu v 27 Sep 2022, 14:06, upravené celkom 1 krát.

romiadam
Ultimate člen
Ultimate člen
Príspevky: 4418
Dátum registrácie: 09 Apr 2008, 00:00
Bydlisko: Wicklow, Irsko
Vek: 47

Re: Lokalna premenna - ujasnenie

Príspevok od používateľa romiadam » 27 Sep 2022, 12:06

Dakujem pekne za odpovede. Vidim, ze sa to vysvetlilo viac nez bolo treba. Teraz to uz chapem. :thumbup:
Dakujem.
0
Prepáčte mi za diakritiku a preklepy - väčšinou píšem z mobilu a ENG klavesnice.
(výroky nemenovaného člena fóra:) ...základy elektrotechniky ovládam dokonale, tak napr. taký tyristor neviem ako presne funguje

Napísať odpoveď