[Risolto]Definire variabili locali una sola volta

Ciao,

vorrei capire se è possibile definire variabili locali, quindi all'interno di una funzione, solo la prima volta che la funzione viene chiamata.

Mi spiego, ho un programma di questo tipo:

void setup(){

}


void loop(){

blink();

}

in un altro file .ino

void blink(){

/* DEFINIZIONE VARIABILI LOCALI*/
*
*
*
/* FINE DEFINIZIONE VARIABILI LOCALI*/

/* SETUP */
*
*
*
/* FINE SETUP*/


/* COSE DA FARE*/
*
*
*
/*FINE COSE DA FARE*/

}

il mio obbiettivo è creare delle funzioni che siano quasi del tutto svincolate dal programma che le richiamerà. Ogni funzione sarà un piccolo programma a se stante e non potrà essere chiamato in "contemporanea" ad un altra funzione.

Non riesco a capire se è possibile definire le variabili una sola volta e non ad ogni chiamata di funzione. Ovviamente se uso una flag con un if, le variabili entrano nella funzione if e il gioco non sta più in piedi. Le variabili dovrebbero poter essere re-impostate solo entrando in un'altra funzione almeno una volta, e successivamente tornare alla funzione precedente.

Siccome ogni funzione è inserita in un file separato dal programma principale, ho pensato di dichiarare le variabili come static, ma, utilizzando lo stesso nome per una variabile (posta in due funzioni diverse), non riesco a compilare. Come mai? La dichiarazione static non serve proprio a quello?

esempio:

/* DEFINIZIONE VARIABILI LOCALI*/
*static int pincopallo = 0;
*
*
/* FINE DEFINIZIONE VARIABILI LOCALI*/

void blink(){

/* DEFINIZIONE VARIABILI LOCALI*/
*
*
*
/* FINE DEFINIZIONE VARIABILI LOCALI*/

/* SETUP */
*
*
*
/* FINE SETUP*/


/* COSE DA FARE*/
*
*
*
/*FINE COSE DA FARE*/

}
/* DEFINIZIONE VARIABILI LOCALI*/
*static int pincopallo = 0;
*
*
/* FINE DEFINIZIONE VARIABILI LOCALI*/

void blink_veloce(){


/* SETUP */
*
*
*
/* FINE SETUP*/


/* COSE DA FARE*/
*
*
*
/*FINE COSE DA FARE*/

}

Nel progetto reale, ad ogni funzione deve corrispondere un gioco di luci (strisce led), ecco perchè non ci saranno più funzioni attive in contemporanea.

Insomma mi servirebbe qualche delucidazione, se si è capito cosa voglio fare :slight_smile:

Praticamente vorresti delle variabili locali ad una funzione (quindi non visibili all'esterno) che conservino il loro valore tra varie chiamate.
Se devono avere un valore costante basta aggiungere const alla dichiarazione, per impedire tutte le nuove scritture.
Se ddvono poter essere modificate basta aggiungere static alla dichiarazione, e fa (o almeno io ho capito dovrebbe fare) quello che ti ho descritto

Si vorrei che il valore fosse conservato e non riazzerato ad ogni chiamata, ma solo quando decido io.

Pensavo infatti di poter mettere una pezza dichiarando le variabili static, in modo da non dovermi preoccupare di variabili omonime tra una funzione e l'altra. Però non compila

Ok ci sono, la variabile static va dentro la funzione, io la mettevo fuori :stuck_out_tongue: in questo modo posso riazzerare le variabili solo quando voglio io, perfetto :slight_smile:

doppiozero:
Ok ci sono, la variabile static va dentro la funzione, io la mettevo fuori :stuck_out_tongue: in questo modo posso riazzerare le variabili solo quando voglio io, perfetto :slight_smile:

Una variabile locale deve essere definita nella funzione dove é valida.
Definita fuori dalle funzioni o é globale se definita in un altra funzione non esiste nella funzione.

Ciao Uwe

Si, solo che avevo capito che se dichiarata static poteva stare fuori dalla funzione, a patto che tutta la funzione fosse in un file separato dal programma principale.

Dal K&R seconda edizione, pag 83, static variables

Static storage is specified by prefixing the normal declaration with the word static. If the two routines and the two variables are compiled in one file, as in

static char buf[BUFSIZE]; /*buffer for ungetch*/
static int bufp = 0; /*next free position  in buf*/

int getch (void) { ...}  
void ungetch (int c) { ...}

then no other routine will be able to access buf and bufp, and those names will not conflict with the same names in other files of the same program.

https://www.arduino.cc/reference/en/language/variables/variable-scope--qualifiers/scope/
https://www.arduino.cc/reference/en/language/variables/variable-scope--qualifiers/static/
https://www.arduino.cc/reference/en/language/variables/variable-scope--qualifiers/volatile/
https://www.arduino.cc/reference/en/language/variables/variable-scope--qualifiers/const/

Una variabile esterna "globale" può essere dichiarata static, e ha visibilità limitata al file in cui è definita, quindi non sarà visibile in altri file.
A mio avviso è poco utile dichiarare una variabile esterna static. :slight_smile:

doppiozero:
Siccome ogni funzione è inserita in un file separato dal programma principale, ho pensato di dichiarare le variabili come static, ma, utilizzando lo stesso nome per una variabile (posta in due funzioni diverse), non riesco a compilare. Come mai? La dichiarazione static non serve proprio a quello?

Hai risolto come static locale alla funz, però:
si, lo static puoi anche usarlo come dici. Perchè non ti compila ? Strano. Potrebbe essere che hai sbagliato qualcosa oppure il problema è come compila Arduino IDE i vari pezzi. Hai messo le funzioni in file separati. Separati come ?
Che estensione prendono i file dove hai le funzioni ?

@uwe - grazie, mi guardo i link

@torn24 - potrebbe essere utile nel mio caso, infatti voglio separare il più possibile le funzioni dal programma principale

@nid - di seguito un esempio che non compila

programma principale:

void setup() {
  // put your setup code here, to run once:

}

void loop() {
funzione_uno();
funzione_due();

}

funzione_uno.ino (altra scheda)

static byte i;

void funzione_uno(){
  
}

funzione_due.ino (altra scheda)

static byte i;

void funzione_due(){
  
}

funzione_uno:3: error: redefinition of 'byte i'
static byte i;
** ^**
/tmp/arduino_modified_sketch_814647/funzione_due.ino:2:13: note: 'byte i' previously declared here
static byte i;
** ^**
exit status 1

Io ho l'impressione che con ide arduino puoi separare il codice in più file, ma poi viene considerato come se il codice fosse tutto in un unico file, altrimenti non mi spiegherei il messaggio di errore che dice che la variabile è definita più volte...

Non succede cosi in un ide e compilatore "normale" per linguaggio C.

torn24:
Io ho l'impressione che con ide arduino puoi separare il codice in più file, ma poi viene considerato come se il codice fosse tutto in un unico file, altrimenti non mi spiegherei il messaggio di errore che dice che la variabile è definita più volte...

Esatto, i vari "tab" che si creano sono SOLO a fini di leggibilità, ma vengono messi TUTTI assieme e compilati come un unico sorgente.

Quello che conviene fare e dei moduli .c/.cpp/.h ed includerli come si fa con le librerie.

Guglielmo

volendo mantenere il concetto della divisione per TAB potrebbe gestire/risolvere il problema della visibiltà delle variabili, in questo caso variabili con lo stesso nome, definendo dei namespace specifici.

ORSO2001:
... potrebbe gestire/risolvere il problema della visibiltà delle variabili, in questo caso variabili con lo stesso nome, definendo dei namespace specifici.

... tanto per rendere "complicata" una cosa semplice :smiley: :smiley: :smiley:

Guglielmo

In questo caso mi sta bene utilizzare le variabili static all'interno della funzione, però volevo capire come mai non riuscivo a compilare portandole fuori. Ora mi è chiaro :slight_smile:

Grazie a tutti dei suggerimenti :slight_smile: