Go Down

Topic: Funzioni in C (Read 15562 times) previous topic - next topic

Dorsai

May 24, 2013, 06:35 pm Last Edit: May 24, 2013, 08:00 pm by leo72 Reason: 1
Vi chiedo gentilmente un aiuto per comprendere meglio le funzioni.

Ho letto che è possibile passare dei parametri ad una funzione e di riceverne di ritorno dei risultati.
Però ho visto che se una variabile è definita come globale all'inizio del programma e questa variabile muta all'interno della procedura, quando la funzione termina, viene comunque restituito il nuovo valore che la variabile ha assunto dentro la funzione.
Dunque non capisco il senso di RETURN e nemmeno il motivo per cui vanno usate funzioni in cui si passano parametri.
Ad esempio ho scritto questa procedura per tarare i sensori di flessione dando avvisi luminosi per sapere quando vanno tenuti diritti e quando vanno piegati.
Code: [Select]
void taratura() {
 digitalWrite (8, HIGH);
 delay (4000);
 for (int z=1; z<20; z++){
   digitalWrite (8, HIGH);
   delay ((200)-(9*z));
   
 max1 = analogRead(1);
  max2 = analogRead(2);
  max3 = analogRead(3);
  max4 = analogRead(4);
  max5 = analogRead(5);
  digitalWrite (8, LOW);
  }
 delay (1000);
 digitalWrite (7, HIGH);
 delay (4000);
  for (int z=1; z<20; z++){
   digitalWrite (7, HIGH);
   delay ((200)-(9*z));
 min1 = analogRead(1);
 min2 = analogRead(2);
 min3 = analogRead(3);
 min4 = analogRead(4);
 min5 = analogRead(5);
 digitalWrite (7, LOW);
  }
 delay (1000);
 }


All'uscita della procedura ottengo i valori necessari per stabilire i range entro cui far ruotare i servo.

edit by mod: includere il codice usando gli appositi tag

uwefed

Funzione banalissima per dimostrare le potenzialitá delle funzioni:

Code: [Select]
int somma ( int A ,int B)
{
return (A+B);
}

adesso se vuoi fare la somma di 2 variabli chiami la funzione e gli dai le due vaiabili:

Code: [Select]
risultato = somma ( variabileA, VariabileB);

se adesso vuoi fare la somma di due altri variabili e ti serve il risultato in un altra variaible

Code: [Select]
sum = somma ( variabileC , VariabileD);

cosí puoi usare una funzione per qualsiasi variabile dello sketch che lavorando con variabili globali senza passare dei valori alla funzione non sarebbe possibile.

Ciao Uwe

yoshi93

Le funzioni ti permettono di riutilizzare il codice, evitando ripetizioni. Poichè i parametri sono variabili locali della funzione si riducono anche le possibilità di fare errori grossolani come modificare qualcosa che serve ancora o dichiarare una stessa variabile e poi usarla per due cose contemporaneamente all'interno del codice.
In progetti molto grandi aiutano a mantenere il codice leggibile e a modificarlo anche dopo mesi che non lo guardi più.
Infine aiutano nel lavoro di squadra permettendo una divisione dei compiti altrimenti impossibile.

nid69ita

Le spiegazioni precedenti sono perfette.
Mi permetto di aggiungerti un esempio:

Nel tuo sketch hai usato ad esempio la funzione    digitalWrite (7, LOW);
Perciò il primo parametro varrà 7 e il secondo LOW.
Se non esistessero i parametri tu dovresti passare i due valori attraverso due variabili globali di cui dovresti anche conoscerne il nome, oltre a sapere che la digitalWrite si aspetta 2 valori.
my name is IGOR, not AIGOR

testato

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

uwefed


testato

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72


Maurotec


x iscrizione


No, non ci credo, testato non ha ancora capito come usare le funzioni. ]:D

Ciao.

Dorsai

Grazie per le spiegazioni.
Ho capito che in una visione organica del codice usare variabili globali anche all'interno delle funzioni può risultare pericoloso.
Tuttavia la cosa è possibile e presenta anche i suoi vantaggi visto che non è necessario passare i dati nella chiamata o restituirne altri al termine della funzione.
L'esempio della somma di due variabili è perfetto per spiegare i vantaggi del passare i dati, mentre se devo attivare la rotazione in un senso o nell'altro di un motore mi limiterò a settare i pin necessari dentro le funzioni (facendone due, una per la rotazione oraria e l'altra per quella antioraria) senza bisogno di trasferimento di valori.
Potrei anche farne una sola, ma concettualmente mi sembra che chiamare le funzione "motoresu" o "motoregiu" è più semplice che definirne una sola generica "motore" e poi dover ricordare i valori da passare per la salita o la discesa.

Grazie ancora  :)

testato

#10
May 25, 2013, 05:32 pm Last Edit: May 25, 2013, 05:42 pm by Testato Reason: 1
Mauro non è che non so come usarle, non le conosco proprio  :)

Onestamente anche io le uso sempre senza argomenti e dichiarate void, usando a palla variabili globali.
Mi risulta tutto piu leggibile e facile

Mai scritta la parola Return in vita mia
Ci sono grosse controindicazioni ?

L esempio motore su e giu mi sembra molto calzante. Inoltre divido a piu non posso le funzioni in tab diverse e mi risulta tutto leggibile e ordinato invece di lunghissimi codici su tab singola ,
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

yoshi93

@Dorsai:
Quelle che fai tu sono procedure (praticamente funzioni senza return o meglio, con return da solo senza valore e implicito nel caso non fosse messo). Come indica il nome sintetizzano il concetto di richiamo di una procedura fissata per fare qualcosa di già esistente. Le funzioni vengono usate più che altro quando si fa ha che fare con algoritmi complessi che è più facile vedere come blocchi che comunicano tra loro. Le funzioni dopotutto derivano dalla matematica dove servono per unire operazione e operandi in nuovi operandi più gestibili (tan(x) la tratti come la tangente di x e ti le concatenazioni più chiare).

@Testato:
In ambito di microcontrollori a 8 bit e semplici firmware le procedure ci possono stare (anzi, danno virtualmente meno problemi in esecuzione perchè richiedono meno memoria che è anche determinabile con sicurezza) mentre se si va su cose più raffinate è meglio introdurre anche qualche funzione. Le procedure se sono molto piccole si potrebbero dichiarare inline così non hai nemmeno l'overhead (poi dipende anche dalla qualità del compilatore che dovrebbe capire come ottimizzare il codice).

testato

Grazie yoshi della conferma e chiarificazione.
Da oghi quindi le chiamo procedure  :)

Hai il tuo primo karma  :)

Che significa inline ed overhead ? 
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72

Paese che vai, nome che trovi.
Le funzioni senza parametri io le chiamo "routine". Sono entrambi nomi validi ed indicano come "funzione" un blocco di programma separato dal loop principale che può essere chiamato da più punti del programma, sia dal loop che da altre funzioni.

Detto questo, le funzioni o le procedure/routine servono per semplificare il programma. Esse vanno a sostituire dei blocchi di codice ripetitivi. L'esempio del digitalWrite è esplicativo: dentro al digitalWrite ci sono diversi controlli: esistono delle chiamate a delle macro che trasformano il numero di pin logico nel piedino fisico del microcontrollore, viene controllato se il pin è capace di Pwm, in caso affermativo viene spento questo segnale, e poi viene impostata il registro della porta per generare lo stato voluto. Tutto questo è noioso e lungo da mettere mettiamo 10 volte in un programma. Allora è stata creata la routine o funzione o procedura (chiamala come ti pare) che accetta un numero di pin ed uno stato e provvede ad eseguire quel compito.

Poi non esiste una regola valida per tutti. Non è detto che una funzione alleggerisca il programma. Come ti ha spiegato yoshi, le funzioni appesantiscono l'elaborazione perché nel momento in cui il programma ne incontra una il compilatore deve prevedere di salvare nello stack l'indirizzo del PC (il Program Counter, il registro che punta alla cella di memoria che contiene l'istruzione da eseguire), poi passare gli eventuali valori, saltare alla funzione, eseguirla, salvare eventuali valori da restituire al chiamante, riestrarre il PC, tornare al punto precedente e ripartire da lì.
Quindi se ti fai una funzione per 2 righe di codice secche l'aggravio è superiore ai vantaggi ottenibili.

nid69ita


Paese che vai, nome che trovi. Le funzioni senza parametri io le chiamo "routine". Sono entrambi nomi validi ...


Penso che chi arriva da Basic o Pascal sia abituato a chiamarle procedure (all'italiana) perchè in quei linguaggi vengono distinte dalla funzioni (procedure/function)
my name is IGOR, not AIGOR

Go Up