Go Down

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

testato

ho letto di queste battaglie contro il goto, io non lo conosco essendo un neonato, purtroppo solo a livello di programmazione, ma mi chiedevo cosa ci fosse di diverso dal concetto di procedura in C ?
se scrivo una procedura e la chiamo pippo() e poi la richiamo nel codice varie volte, cosa ha di diverso dallo scrivere goto30 per andare alla linea 30 del basic alla quale linea inizia la mia bella procedura che fa le stesse cose che fa la pippo() in C ?
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72

Il GOTO porta a scrivere quello che gli americani chiamano Spaghetti Code, ossia codice intrecciato nella logica. Diventa difficile seguire un programma se lo infarcisci di GOTO perché invece che di un flusso lineare hai una serie di salti che se ne fregano di if/do/while e quant'altro.

A livello di funzionalità a basso livello non cambia nulla, perché se guardi un codice assembly vedrai una sfilza incredibile di salti. Ma a livello di programmazione ad alto livello, il GOTO rende un sorgente incomprensibile perché semplifica la scrittura del programma e porta il programmatore ad abusarne per ridurre la fatica mentale che dovrebbe fare per scrivere un programma con strutture di controllo tipo quelle citate (if/do/while ecc...)

testato

controlla se ho capito:
se in un while metto
"nel frattempo che x==1 fai pippo()" resto sempre all'interno del while nonostante stia eseguendo pippo(),

invece se faccio
"nel frattempo che x==1 goto 30" esco dal while al primo giro e non ci rientro piu' ?
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

yoshi93

Esatto, il goto potenzialmente rompe tutti i costrutti della programmazione ad alto livello.

BaBBuino

Non so se qualcuno lo ha già detto, ma se una variabile INT la dichiari "static" dentro una funzione, non viene distrutta quando la funzione esce. E se richiami la funzione, ti ritrovi la variabile esattamente come l'avevi lasciata.

testato

#35
May 26, 2013, 08:36 pm Last Edit: May 26, 2013, 09:01 pm by Testato Reason: 1
bella storia quella del goto :)

costant static int e' quindi una via di mezzo rispetto al dichiararla globale ?

visto che siamo in tema, le funzioni base di programmazione, tipo IF (si chiama funzione ?)
dove sono fisicamente, c'e' un file dell'IDE con tutte queste funzioni ?
il sorgente dell IF e' una cosa grande ?
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72


Non so se qualcuno lo ha già detto, ma se una variabile INT la dichiari "static" dentro una funzione, non viene distrutta quando la funzione esce. E se richiami la funzione, ti ritrovi la variabile esattamente come l'avevi lasciata.

E' un modo per non usare una variabile globale ma una variabile locale che non perde il suo valore.

Un esempio:

Code: [Select]

void setup() {
  Serial.begin(19200);
  delay(2000);
}

void loop() {
  stampa();
}

void stampa() {
  static int valore = 0;
  Serial.print(valore++, DEC);
  delay(500);
}


Vedrete sul monitor seriale il valore di "valore" aumentare ad ogni stampa, nonostate ci sia un'assegnazione di 0 a valore subito all'inizio di stampa(). La parola chiave "static" indica al compilatore che il valore di "valore" diventa statico, ossia che non si perde uscito dalla funzione.

leo72


costant int e' quindi una via di mezzo rispetto al dichiararla globale ?

Forse ti riferisci a "static". Ti ho risposto sopra.

Quote

visto che siamo in tema, le funzioni base di programmazione, tipo IF (si chiama funzione ?)
dove sono fisicamente, c'e' un file dell'IDE con tutte queste funzioni ?
il sorgente dell IF e' una cosa grande ?


No, fanno parte del linguaggio stesso, sono intrinseche ad esso.

BaBBuino

No, IF è una ISTRUZIONE del C.

Un insieme di istruzioni (ma anche una eletta a funzione) fanno una funzione.

Esistono Funzioni standard, ovvero del C, come le stdio per funzioni di I/O, oppure math o string per le stringhe.

Poi esistono funzioni di qualche libreria, per esempio di un qualche sensore. Allora deviincludere la libreria dove sono contenute:

Es. Sensore BMP085 di temperatura pressione.
Se vuoi "prendere" la temperatura dovrai usare la funzione di libreria BMP085.GetTemperature, ma essendo scritta dentro una libreria xxxx.H, dovreai includere questo file xxx.H dentro il tuo file .pde


E poi esistono le tue funzioni che ti scrivi te e che fanno i czz tuoi.


Quindi 3 tipi di funzioni:

Standard del C
Funzioni dentro Librerie di qualcosa
Funzioni tue (o anche librerie tue).

Alla fine sono la stessa cosa (come principio)

yoshi93

if, else,while,class ecc. sono parole riservate del linguaggio perchè specificano un costrutto del linguaggio stesso. La loro definizione è in codice assembly e la fa il compilatore quindi per vedere come sono implementate bisogna guardare nei sorgenti del compilatore.
La parola riservata static dentro funzioni e classi serve per definire una variabile allocata nella memoria statica e non nello stack quindi persistente tra varie chiamate alla funzione o istanziazione della classe. Fuori dalla funzione indica un linkage interno percui evita di avere collisioni tra nomi uguali in file diversi.

[Static va usata con cura nei progetti molto grossi dove ci sono più oggetti che dipendono uno dall'altro perchè può dare luogo ad errori di linkaggio dipendenti dalla piattaforma(quindi molto difficili da trovare)].

BaBBuino


if, else,while,class ecc. sono parole riservate del linguaggio perchè specificano un costrutto del linguaggio stesso. La loro definizione è in codice assembly e la fa il compilatore quindi per vedere come sono implementate bisogna guardare nei sorgenti del compilatore.
La parola riservata static dentro funzioni e classi serve per definire una variabile allocata nella memoria statica e non nello stack quindi persistente tra varie chiamate alla funzione o istanziazione della classe. Fuori dalla funzione indica un linkage interno percui evita di avere collisioni tra nomi uguali in file diversi.

[Static va usata con cura nei progetti molto grossi dove ci sono più oggetti che dipendono uno dall'altro perchè può dare luogo ad errori di linkaggio dipendenti dalla piattaforma(quindi molto difficili da trovare)].



Ti prego di scusare la mia critica, ma il tuo eccellente e accademco modo di esporre la descrizione della domanda è di quel tipo che non fa capire nulla al principiante. Sono cioè, quelle spiegazioni, ottime per chi sa già di cosa si parla! (non tirarmi delle pietre ora...) :D

testato

#41
May 26, 2013, 09:05 pm Last Edit: May 26, 2013, 09:06 pm by Testato Reason: 1
vanno bene entrambe le spiegazioni :)

quindi per fare un esempio pratico, volendo qppunto guardare dentro al compilatore, l'IF arduinico dove e' ? oppure e' a sua volta compilato e quindi non lo si puo' vedere ?
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

yoshi93

Per chi non avesse capito nulla schematizzo  :):

1)Le parole riservate di un linguaggio sono definite nel compilatore come sequnza di istruzioni a più basso livello.

2)Static ha una doppia funzionalità, la prima è quella di fare una variabile che mantiene il valore tra le chiamate a una funzione o tra più oggetti della stessa classe,la seconda è quella di evitare conflitti di nomi tra variabili di diversi file in progetti molto grossi.

3)Static va usata con cura nei progetti moooolto grossi perchè in fase di link(cioè quando i vari pezzi del programma vengono saldati assieme) se due oggetti dipendono uno dall'altro e hanno variabili static all'interno possono succedere errori che dipendono dalla precedenza che il linker assegna alla allocazione delle variabili. Un programma che funzionava quindi può dare errori se compilato con linker diverso.

Il compilatore di solito è compilato (bel gioco di parole vero?) quindi non si può vedere granchè. Potresti però studiare compilatori open source.

leo72


fanno parte del linguaggio stesso, sono intrinseche ad esso.

Come detto, non trovi il "sorgente" del linguaggio base C perché è "dentro" al compilatore.

BaBBuino

#44
May 26, 2013, 09:17 pm Last Edit: May 26, 2013, 09:34 pm by leo72 Reason: 1
Le istruzioni del C sono direttamente compilate dal... compilatore in assembler del tipo richiesto (x86, PIC, ATMega, PARALLAX ecc.) e anche all'interno di una stessa architettura, compilatori diversi compilano in maniera leggermente differente la stessa istruzione.

Quindi aspettati una roba del genere:


Code: [Select]
------------------------

49: // Esempio inizializzazione e somma tra int
50: if (intA == 5);
00DE 0E05 MOVLW 0x5
00E0 6EF3 MOVWF 0xff3, ACCESS
00E2 0E03 MOVLW 0x3
00E4 CFF3 MOVFF 0xff3, 0xfdb
00E6 FFDB NOP
00E8 0E04 MOVLW 0x4
00EA 6ADB CLRF 0xfdb, ACCESS
51: intB = 8;
00EC 0E08 MOVLW 0x8
00EE 6EF3 MOVWF 0xff3, ACCESS
00F0 0E05 MOVLW 0x5
00F2 CFF3 MOVFF 0xff3, 0xfdb
00F4 FFDB NOP
00F6 0E06 MOVLW 0x6
00F8 6ADB CLRF 0xfdb, ACCESS
52:
53: intC = intA + intB;
00FA 0E05 MOVLW 0x5
00FC CFDB MOVFF 0xfdb, 0x2
00FE F002 NOP
0100 0E06 MOVLW 0x6
0102 CFDB MOVFF 0xfdb, 0x3
0104 F003 NOP
0106 0E03 MOVLW 0x3
0108 50DB MOVF 0xfdb, W, ACCESS
010A 2402 ADDWF 0x2, W, ACCESS
010C 6E00 MOVWF 0, ACCESS
010E 0E04 MOVLW 0x4
0110 50DB MOVF 0xfdb, W, ACCESS
0112 2003 ADDWFC 0x3, W, ACCESS
0114 6E01 MOVWF 0x1, ACCESS
0116 0E07 MOVLW 0x7
0118 C000 MOVFF 0, 0xfdb
011A FFDB NOP
011C 0E08 MOVLW 0x8
011E C001 MOVFF 0x1, 0xfdb
0120 FFDB NOP

Go Up