Arduino Forum

International => Italiano => Software => Topic started by: pippopippoli on Dec 19, 2013, 05:50 pm

Title: come funziona void
Post by: pippopippoli on Dec 19, 2013, 05:50 pm
salve a tutti ho scoperto che oltre al void setup e void loop posso creare un void tutto mio tipo void gianluca ,
ma non sono riuscito a capire come farlo partire e chiudere
non ho trovato niente su google come funziona?
Title: Re: come funziona void
Post by: PaoloP on Dec 19, 2013, 06:00 pm
Il linguaggio utilizzato da Arduino sono il C e il C++.
Le funzioni sono parte di questo linguaggio.
Per capirne il funzionamento puoi dare uno sguardo qui --> http://www.html.it/pag/15409/le-funzioni/
oppure qui --> http://cpiupiu.altervista.org/
Qui c'è un buona guida al C in generale ma è applicabile con alcuni accorgimenti ad Arduino --> http://blacklight.gotdns.org/guidac.pdf (http://blacklight.gotdns.org/guidac.pdf)
Title: Re: come funziona void
Post by: nid69ita on Dec 19, 2013, 06:24 pm

salve a tutti ho scoperto che oltre al void setup e void loop posso creare un void tutto mio tipo void gianluca ,
ma non sono riuscito a capire come farlo partire e chiudere
non ho trovato niente su google come funziona?


Dato il nome deciso da te, dove vuoi eseguirlo, scrivi il nome e poi apri e chiudi la tonda.
Esempio stupido:
Code: [Select]

const byte pinLed=13;
void setup()
{ delay(1000);
  pinMode(pinLed,OUTPUT);
}

void ledOn()
{ digitalWrite(pinLed,HIGH);
}

void ledOff()
{ digitalWrite(pinLed,LOW);
}

void loop()
{ ledOn();
  delay(1000);
  ledOff();
  delay(1000);
}
Title: Re: come funziona void
Post by: leo72 on Dec 19, 2013, 09:06 pm
Aggiungo a quanto ti hanno già detto: "void" da solo significa "nulla", e messo prima del nome di una funzione indica che tale funzione non restituisce al chiamante nessun valore, vuol dire che vengono chiamate, eseguono il codice che contengono e poi restituiscono il controllo al programma chiamante.

Title: Re: come funziona void
Post by: Etemenanki on Dec 20, 2013, 12:03 pm
Scusa se mi inserisco, forse e' una domanda stupida, ma poniamo il caso che io voglia farmi delle funzioni tipo quella, ma che devono restituire qualcosa (ad esempio, una funzione che, richiamata solo quando mi serve, mi vada a leggere dei sensori analogici, esempio, NTC o fotocellula o volt, quello che vuoi, e che sia in grado di riportare il valore letto al programma principale sotto forma di variabile) ... quale sarebbe il modo migliore di farlo ? ... intendo, sempre come funzione richiamabile a comando come la void, non come parte del programma che continua a girare ...
Title: Re: come funziona void
Post by: PaoloP on Dec 20, 2013, 12:10 pm
Hai vari modi.
Se ti serve un solo parametro dichiari la funzione in base al tipo di parametro da restituire e usi il comando return all'interno della funzione.
Se sono più parametri li puoi passare alla funzione come puntatori e la funzione li manipola poi restituendoli modificati.
Potresti infine usare dei parametri globali singoli o organizzati in una struttura (C) o in una classe (C++).
Title: Re: come funziona void
Post by: gpb01 on Dec 20, 2013, 12:12 pm

Scusa se mi inserisco, forse e' una domanda stupida, ma poniamo il caso che io voglia farmi delle funzioni tipo quella, ma che devono restituire qualcosa ...


Così :

Code: [Select]
tipo_da_restituire nome_funzione(tipo_parametri parametri) {
  ....
  ....
  <<implementazione>>
  ....
  ....
  return valore_da_restituire;
}


... o non ho capito la domanda ???  :smiley-roll:

Guglielmo
Title: Re: come funziona void
Post by: Etemenanki on Dec 20, 2013, 12:19 pm
gpb01: Fondamentalmente mi chiedevo se c'erano funzioni tipo la "void" (che non restituisce nulla), ma gia previste per restituire valori ... oppure se era necessario usare sempre "void", ma trasferendo i valori in un modo diverso, dato che di per se non lo fa (a quanto ho capito)

O in alternativa, se per fare una cosa simile, fosse necessario scriversi una specifica libreria ... cosa molto piu complessa ...


EDIT: PaoloP, potrebbe essere anche un solo parametro, al limite ... ad esempio, se fosse una funzione per leggere una temperatura solo quando serve, il dato sarebbe, alla fine, solo una variabile numerica contenente un singolo valore ...
Title: Re: come funziona void
Post by: gpb01 on Dec 20, 2013, 12:29 pm

gpb01: Fondamentalmente mi chiedevo se c'erano funzioni tipo la "void" (che non restituisce nulla), ma gia previste per restituire valori ... oppure se era necessario usare sempre "void", ma trasferendo i valori in un modo diverso, dato che di per se non lo fa (a quanto ho capito) ...


Scusa, sarò io che non capisco ... ma quando, ad esempio, usi analogRead() ... quella è una funzione che ti ritorna un valore ... per l'esattezza un int ... quindi ... tu che vuoi sapere esattamente ???

Guglielmo
Title: Re: come funziona void
Post by: nid69ita on Dec 20, 2013, 01:56 pm
@Guglielmo, credo @Eteme voglia fare una procedura (funzione con void) a cui passa dei parametri modificabili ma non ritorna nulla.

Si, @Eteme puoi, come detto da @PaoloP

Riassumendo:
1. se non devi restituire nulla fai una funzione void (che in altri linguaggi si chiamano procedura o sub)
2. se devi ritornare un solo valore fai una funzione dichiarando davanti al posto del void il tipo del ritorno (e in altri linguaggi le chiamano funzioni)
3. se devi ritornare più valori, di solito fai una funzione (void oppure no) che manipola i parametri (alcuni o tutti) che passi. Quindi quei parametri saranno dal punto di vista della funzione sia in input che in output. Alcuni parametri però in C vengono passati per valore (sono una copia del valore originale) perciò bisogna usare i puntatori per permettere alla funzione di cambiare i valori della variabile passata.
Title: Re: come funziona void
Post by: Etemenanki on Dec 20, 2013, 02:27 pm
Se esiste il modo di scriversi una funzione "complessa", diversa da quelle gia esistenti, in grado di eseguire piu comandi, e trasferire anche valori, all'occorrenza ...

Ad esempio, il tuo riferimento all'analogread, quella e' una funzione gia esistente, che legge un valore analogico da un'ingresso (se non sbaglio), e lo mette in una variabile, ma fondamentalmente fa solo quello ... poniamo invece, ad esempio, il caso che tu debba eseguire anche altre funzioni connesse alla tua lettura, funzioni per le quali non hai un comando gia pronto ... se ho capito bene il discorso della "void", questa ti permette di crearti delle funzioni (chiamiamole "pacchetti di comandi", se vuoi), e di richiamarle quando ti servono, ma non restituisce nulla al programma ...

Se invece io volessi, sempre come esempio, eseguire diverse funzioni, il cui risultato finale e' una lettura analogica, e poi avere questo risultato trasferito indietro al corpo principale del programma, ma senza doverle riscrivere ogni volta che servono, e senza che rimangano sempre in esecuzione, il modo piu semplice che mi viene in mente e' di metterle in una "funzione" (o insieme di funzioni), e richiamarla solo nei momenti in cui mi serve ... in questo caso, per restituire il valore ad una variabile nel corpo principale una volta che la "funzione" e' terminata, il sistema migliore quale sarebbe ? ... creare una funzione specifica, o usare un "return" che spedisca il valore ad una variabile "esterna" alla mia "funzione" ?

Faccio un'esempio stupido, metti che debba campionare una serie di temperature dopo aver spostato una sonda ed atteso un tempo di stabilizzazione, ma che il tutto lo debba fare solo quando premi un pulsante (era una cosa che avevo fatto secoli fa in basic, e' il primo esempio che mi e' venuto in mente :P) ... dovrei fare qualcosa di simile:

un "corpo" principale
....
....
.... (istruzioni)
quando  il pulsante 1 e' premuto, richiama "funzione1"
elabora "x"
....
....
.... (altre istruzioni)
ecc

ed una sottofunzione tipo:

"funzione1"
   sposta la sonda
   attendi 10 secondi
   (loop) leggi 10 valori e mettili in un'array
   fai la media del contenuto dell'array
   "x"=risultato
   ritira la sonda
   torna a principale (ovviamente nel punto da cui e' stata lanciata "funzione1")
fine "funzione1"

che venga richiamata dal corpo principale solo quando serve (potrebbero anche essere piu funzioni differenti, per eventi diversi) ... e cosi via ... (scusa il linguaggio "da profano" ... lo so che magari a voi la domanda sembra stupida, come quando chiedono a me che differenza c'e' fra tensione e corrente :P ... ma sto ancora cercando di impararla, la programmazione delle MCU) ... a livello di programmazione Arduino, o comunque MCU Atmel, e' una cosa possibile, o non e' supportata e bisogna usare una struttura completamente differente ?
Title: Re: come funziona void
Post by: gpb01 on Dec 20, 2013, 02:37 pm
Etem,
come fare te l'ho fatto vedere 3 post sopra, inoltre ...
... non hai limiti al numero di funzioni che puoi creare e le chiami solo quando ti servono.

Ogni funzione, può o non può tornare un valore.  Se NON torna alcun valore, per farlo capire al compilatore, si usa la parolina magica "void" che, appunto, indica che il compilatore NON deve aspettarsi indietro nessun valore dalla funzione.  Se la funzione ritorna un valore, allora devi dire quale è il tipo di valore che ritorna : byte, char, int, long int. .... e così via.

La funzione è quindi un blocchetto che fa sempre una determinata cosa ... la analogRead() legge il valore del convertitore ADC e ti ritorna questo valore in un int che tu assegni ad una variabile, quindi ... nel tuo programma, quando ti serve di leggerlo farai :

mio_valore = analogRead(Ax);

il controllo passerà temporaneamente alla funzione che, fatta la lettura, restituirà il valore che verrà assegnato alla tua variabile.

Allo stesso identico modo tu ti crei la TUA funzione che, nel tuo esempio, campiona la temperatura e ti ritorna il risultato ...
... quando ti serve la chiami, quella va in esecuzione, ritorna indietro il valore e tu assegni questo valore ad una tua variabile e prosegui con il tuo programma. Se ti riserve, la richiami di nuovo e così via ...

Più chiaro adesso ?

Guglielmo
Title: Re: come funziona void
Post by: nid69ita on Dec 20, 2013, 02:39 pm
@Eteme  non capisco bene.
Quello che fa la tua funzione dipende da te e può essere complessa quanto vuoi. Può richiamare a sua volta altre funzioni da te create.
L'istruzione return si usa solo nel caso di funzione non void che deve ritornare un dato del tipo dichiarato.

Scusa @Guglielmo se mi sovrappongo  :)
Title: Re: come funziona void
Post by: PaoloP on Dec 20, 2013, 05:23 pm
Per incasinare il discorso  ]:D diciamo pure che il C++ permette l'overloading delle funzioni.
Ovvero puoi avere più funzioni con lo stesso nome ma parametri in ingresso diversi e il compilatore sceglie quella che corrisponde ai parametri.
Il tipo di funzione (int, float, ecc), il parametro restituito e il codice interno può essere diverso da funzione a funzione.
Title: Re: come funziona void
Post by: Etemenanki on Dec 20, 2013, 05:35 pm

Se la funzione ritorna un valore, allora devi dire quale è il tipo di valore che ritorna : byte, char, int, long int. .... e così via.


Questo lo devo dichiarare nel "setup", solo all'inizio, se non ho capito male :P

Quote

... mio_valore = analogRead(Ax);

il controllo passerà temporaneamente alla funzione che, fatta la lettura, restituirà il valore che verrà assegnato alla tua variabile.
...

Più chiaro adesso ?


Un po piu chiaro, si (abbi pazienza, io sono cresciuto a gwbasic e basta :P) ... era la struttura della chiamata che mi fregava nel ragionamento ... quindi, secondo il tuo esempio, la chiamata della funzione (analogread) e' l'azione stessa di assegnarla come valore alla variabile ... io invece ragionavo (sbagliando) con la sequenza "chiama funzione > esegui funzione > funzione assegna valore a variabile > ritorna > usa variabile", (e li mi incasinavo :P) ... mentre il tuo esempio "mio_valore = analogRead(Ax);", chiama la funzione semplicemente assegnando il valore della funzione alla variabile ... inizia a calare la nebbia ;)

Solo un dubbio, questo tipo di struttura di richiamo comporta sempre che la funzione restituisce il controllo al punto in cui e' stata chiamata, giusto ? ... se invece dovesse condizionare il punto di rientro al valore restituito, dovrei farlo dopo il rientro usando degli if o dei case, non potrei farlo dall'interno della funzione stessa ...


Quote
L'istruzione return si usa solo nel caso di funzione non void che deve ritornare un dato del tipo dichiarato.


Questa devo studiarmela con calma ...



Quote
Per incasinare il discorso   ]:) diciamo pure che il C++ permette l'overloading delle funzioni.
Ovvero puoi avere più funzioni con lo stesso nome ma parametri in ingresso diversi e il compilatore sceglie quella che corrisponde ai parametri.
Il tipo di funzione (int, float, ecc), il parametro restituito e il codice interno può essere diverso da funzione a funzione.


Grazie, mi mancava un'altro po di confusione ... :P XD
Title: Re: come funziona void
Post by: PaoloP on Dec 20, 2013, 05:37 pm

Questo lo devo dichiarare nel "setup", solo all'inizio, se non ho capito male :P


No, la dovresti dichiarare subito dopo gli #include e i #define come prototipo di funzione ma ci pensa l'IDE di Arduino a farlo, quindi sei esonerato da questo compito.
Title: Re: come funziona void
Post by: gpb01 on Dec 20, 2013, 06:17 pm

....
Questo lo devo dichiarare nel "setup", solo all'inizio, se non ho capito male :P


Il guaio è che usi l'IDE che, per semplificare la vita a chi inizia, nasconde tutta una parte ... ma va bene ...

Allora, normalmente in C si dovrebbe sempre dichiarare in testa al programma (più o meno dove dichiari le costanti, le variabili globali, ecc) le funzioni che usi, descrivendo i parametri che esse vogliono e il valore che esse ritornano, cioè ... occorrerebbero i "prototipi delle funzioni" es. :

Code: [Select]
int analogRead(int);

questo è il prototipo, poi, da qualche parte c'è l'implementazione della funzione :

Code: [Select]
int analogRead(int pinNumber) {
  ....
  ....
  return il_valore
}


tutto questo l'IDE te lo nasconde e, quando dichiari una TUA funzione ... di nascosto il prototipo lo fa lui. Se usi Atmel Studio invece ... o altri ambienti di sviluppo, i prototipi li devi mettere tu.



Un po piu chiaro, si (abbi pazienza, io sono cresciuto a gwbasic e basta :P) ... era la struttura della chiamata che mi fregava nel ragionamento ... quindi, secondo il tuo esempio, la chiamata della funzione (analogread) e' l'azione stessa di assegnarla come valore alla variabile ...


Allora .. nessuno ti vieta di chiamare la funzione direttamente

Code: [Select]
analogRead(pin);

... solo che così ... ti perdi il valore di ritorno, visto che il compilatore non sa a chi dare l'int di ritorno e quindi lo butta via  XD

Se la funzione torna un valore, magari quel valore ti serve (o magari no) ... e quindi tu dici al compilatore di prendere il valore di ritorno ed assegnarlo ad una variabile.



Solo un dubbio, questo tipo di struttura di richiamo comporta sempre che la funzione restituisce il controllo al punto in cui e' stata chiamata, giusto ? ... se invece dovesse condizionare il punto di rientro al valore restituito, dovrei farlo dopo il rientro usando degli if o dei case, non potrei farlo dall'interno della funzione stessa ...


Si, in pratica, con la solita regola da destra a sinistra, l'espressione viene valutata ... e dato che incontra l'assegnazione ad una variabile di un qualche cosa che non conosce ... prima chiama la funzione (in pratica si salva il punto in cui sta e salta al punto d'ingresso della funzione) e, quando la funzione è terminata torna dove aveva lasciato assegnando il valore che ora ha ;)



Questa devo studiarmela con calma ...


Immagina void come un "tipo vuoto, inesistente" ... se la funzione deve solo fare delle cose ma non ti deve ritornare nulla (es. pulisci LCD ... deve solo pulire la memoria del LCD ma non ti deve tornare nulla) allora la dichiari di tipo void ovvero da cui non ti aspetti nulla in ritorno e che non contiene il ritorno di un valore (l'istruzione return la può contenere, non deve contenere return valore). Negli altri casi, in cui ti aspetti un valore di ritorno, la dichiarerai del tipo del valore che ti aspetti ti ritorna (byte, char, int ....)



Grazie, mi mancava un'altro po di confusione ... :P XD


Al momento NON stare a sentire chi ti parla di C++ ...  ]:D
... già hai da lavorare parecchio sulle basi ... poi per il C++ c'è sempre tempo ;)

Guglielmo
Title: Re: come funziona void
Post by: paulus1969 on Dec 20, 2013, 07:19 pm




Quote
L'istruzione return si usa solo nel caso di funzione non void che deve ritornare un dato del tipo dichiarato.


Questa devo studiarmela con calma ...




{ ... da qualche parte nel loop
hai dichiarato qui o all'inizio
int x=1; int y=2; int z;
fai
z = somma(x,y);
}

dove sotto costruisci

int somma (int a, int b) {int c = a+b; return c}

una cosa di queste insomma...
Title: Re: come funziona void
Post by: leo72 on Dec 20, 2013, 09:38 pm
Esempio concreto:
Code: [Select]
void flashLed(int flash, byte ledPin) {
  for (int i = 0; i < flash; i++) {
    digitalWrite(ledPin, 1);
    delay(50);
    digitalWrite(ledPin, 0);
    delay(50);
  }
}


Hai una funzione che accetta dei parametri, fa "qualcosa" e non ti restituisce nulla indietro. Semplice e pulita.
Mettiamo invece ora che tu debba sapere dopo l'attivazione di un relé che accende un dispositivo, la lettura di una tensione che ti indicherà un qualcosa.
Code: [Select]

boolean accendiDevice() {
  digitalWrite(pin, HIGH);
  delay(500);
  if (analogRead(sensorPin) < 250) { //errore
    return false;
  } else { //tutto OK
    return true;
  }
}


Questa funzione "fa qualcosa" ma non solo, ti dice anche com'è andata l'operazione.
Se tu ad esempio nel codice scrivi qualcosa del tipo:
Code: [Select]

if (accendiDevice() == FALSE) {
    Serial.println("ERRORE");
}


La "risposta" della funzione diventa l'elemento di test dell'if.
Title: Re: come funziona void
Post by: gpb01 on Dec 20, 2013, 09:48 pm
In realtà, per non confondere le idee a Etem, occorre dire che anche nell'ultimo caso spiegato da Leo c'è un valore di ritorno che viene comunque usato ...

Code: [Select]
if (accendiDevice() == FALSE) {
    Serial.println("ERRORE");
}


... il compilatore esamina da destra a sinistra quell'IF ... FALSE è una costante e quindi ha un valore, poi c'è l'operatore e poi c'è la funzione ... il compilatore non sa il valore della funzione quindi genera un codice che, arrivato a quel punto salta nella funzione, la esegue, prende il valore di ritorno e, tornato indietro, quel valore viene usato come se li ci fosse una variabile che ha assunto quel valore ... quindi può fare il confronto ed agire di conseguenza ;)

Guglielmo

Title: Re: come funziona void
Post by: leo72 on Dec 20, 2013, 09:53 pm
Sì ma difatti l'esempio era proprio per descrivere l'uso di un valore di ritorno.

Se Etem vuol vedere l'uso di un valore di ritorno non usato prende la classe Print, nel file vedrà che ci sono return a tutte le funzioni. Cioè, quando io faccio Serial.print in realtà la funzione mi restituisce qualcosa, solo che io non la uso e faccio cadere quel valore.
Title: Re: come funziona void
Post by: Maurotec on Dec 20, 2013, 10:53 pm
No, non ci credo Etem che non sa programmare.
Pronto,  pronto intervento? si dica.
Emet non sa programmare.
Provvediamo subito, una sacca...no meglio due di programmina, 200 cc di C.  :smiley-mr-green:

Ok, niente di preoccupante, anche io sono passato per gwbasic, quickbasic e basic-7.1.

Il tipo void è necessario perché nelle vecchie versioni di C una funzione di base ritornava sempre un intero, e credo che ancora adesso sia così. Quindi void si usa per dire che la funzione che di default ritorna un intero non deve ritornare nulla. Il C ANSI, richiede anche "void" nella lista di argomenti di funzione quando questa è vuota.
Code: [Select]

void myFunc(void); // protoype

void myFunc(void)
{
    // Questo è un blocco di codice legato ad un nome di funzione richiamabile.
}


Code: [Select]
int yourFunc(void)
{
     // il puntatore PC e qui, non puoi decidere in anticipo cosa accadrà quando la funzione termina.
     // anche perché qui siamo in contesto locale dove le variabili create qui dentro vengono distrutte
     // al termine della funzione.
     int i = 0;
     return i;  // ritorna i, al chiamante e poi la variabile locale i viene distrutta
}


Occhio che viene creata una copia della variabile i e ritornata al chiamante, la copia rimane nello stack del contesto chiamante e viene distrutta nel contesto della funzione.

Immagina cosa accade se al posto di restituire un tipo "int", restituissi un tipo utente, come ad esempio
un oggetto String. Ci vuole più tempo a creare una copia di un oggetto "String" che un oggetto di tipo "int".
Un ogetto String è instanza oggetto di classe String. Nel caso di "int", un oggetto int è instanza oggetto di tipo predefinito fornito dal linguaggio di programmazione. Questa spiegazione è più orientata alla programmazione
ad oggetti e prima che venisse creato il C++ i programmatori C avrebbero detto che myInt è una variabile di tipo int.

Anche gli argomenti (anche detti parametri) di una funzione sono locali al contesto della funzione, perché di default il passaggio di parametri viene effettuato per valore, per cui viene creata una copia della variabile usata come parametro che ha il valore che nella chiamata hai specificato.

Code: [Select]
void myFunc(int x)
{
    // viene creata una variabile "x" locale a cui gli viene assegnato il valore che nella chiamata seguente
    // vale 5.
    x += 1;
}

// chiamata
myFunc(5);


Questo porta a dire che una variabile ha una lifetime, cioè un periodo di vita più o meno lungo.
Le variabili globali hanno un periodo di vita lungo quanto è lunga la vita del programma.
Le variabili locali hanno un periodo di vita più breve rispetto alle variabili globali. Il periodo di vita è determinato
dal blocco {}. Un code block è una entità che può esistere anche non legata ad una istruzione C o ad una funzione.

Code: [Select]
void myFunc()
{
     int i = 0;
     {     //  questo è un code block non legato ad alcuna funzione o istruzione
           int h = 1;
     }
    // int h qui non è più visibile perché non esiste più e posso dichiararla un altra volta.
    int h = 5;
}


Ciao.
Title: Re: come funziona void
Post by: Etemenanki on Dec 21, 2013, 12:25 pm

No, non ci credo Etem che non sa programmare.
...


Credici :P ... gli unici "linguaggi" che avevo imparato un po, erano il gwbasic e l'html, il primo per divertimento ed il secondo per scrivere qualche pagina web (all'epoca usavo il notepad, i programmi per composizione costavano troppo :P) ... poi vuoi per lavoro vuoi per mancanza di tempo, la programmazione non l'ho mai veramente approfondita ... ed ora che mi piacerebbe smanettare un po con qualche MCU semplice, mi tocca imparare tutto da zero.

L'unico "problema", e' che gwbasic ed html li avevo imparati senza nessun corso, semplicemente leggendo il manuale, perche' in fondo sono semplici, mentre C e C++ oltre ad essere "leggermente" piu complessi (:P) hanno anche una struttura completamente differente ... quindi prima di riuscire ad imparare i linguaggi, devo "disimparare" le strutture logiche che usavo prima (ed a 51 anni e con poco tempo a disposizione, non e' facile :P)

Ma non mi arrendo ... o con le buone, o con le cattive, prima o poi ci arrivo  :smiley-roll-blue:
Title: Re: come funziona void
Post by: nid69ita on Dec 21, 2013, 12:52 pm
@etemenaki,  parallelismo con GWBasic:

Una funzione void è come il GOSUB del gwbasic con la differenza che ha un nome e non un numero di linea.
Poi il return del GWbasic indica solo la fine della sottofunzione mentre in C la usi solo se devi ritornare un valore (quindi non lo usi per una void funzione che non ritorna nulla)

Una funzione che ritorna un valore in C la puoi paragonare a "DEF FN Statement" del GWbasic anche se in C può essere molto complessa.
Title: Re: come funziona void
Post by: Maurotec on Dec 21, 2013, 07:28 pm
@nid69ita
Quanti ricordi che tornano alla mente, chissà perché le funzioni C mi sembrano molto più naturali rispetto a quelle del GWBasic.

@Etem
Con la tua competenza in elettronica, se imparassi quello che so io di informatica e programmazione ecc non avresti limiti.

Con il C può aiutare sapere cosa accade quando viene chiamata una funzione. Visto che il C è un linguaggio
compilato il compilatore si deve inventare un modo per realizzare il concetto di funzione.
Lo stak è un area di memoria dove ogni dato è simile ad un piatto, più piatti una pila di piatti.
Il primo piatto posato sul tavolo, il secondo sul primo, il terzo sul secondo e così via.
Questa pila è nota anche con il nome di "lifo" Last input, first output appunto come una pila di piatti, dove
l'ultimo piatto posato prima o poi e destinato a essere preso prima di tutti gli altri.

Una funzione non esiste in assembly, si risolve mettendo i parametri nello stack e saltando ad eseguire codice all'indirizzo in cui c'è il codice della funzione, per cui a quel codice ci deve essere anche una porzione di codice aggiunta dal compilatore per leggere i parametri prendendoli appunto dallo stack. Occhio che prenderli deve essere inteso letteralmente, per cui preso un dato dallo stack verrà messo da qualche parte (es registro CPU) e il dato nello stack non c'è più. Se la funzione deve restituire un valore, il codice allora deve spingere il dato di ritorno nello stack e poi saltare all'indirizzo seguente a quello in cui è avvenuta la chiamata.

Ora non ricordo l'ordine dei dati messi nello stack, ma anche l'indirizzo di ritorno deve stare nello stack, diversamente la funzione non saprebbe l'indirizzo da eseguire al termine della funzione stessa.

Per cui una funzione void, costa meno di una non void che deve spingere il dato nello stack.
Il compilatore per fare la traduzione del codice C in assembly ha di bisogno di queste informazioni.

PS: L'istruzione "return" in una funzione void può essere usato per uscire da una funzione prematuramente, cioè
cose del tipo: if (pointer == NULL) return; e pointer potrebbe essere un argomento a cui la funzione accede, per cui se pointer non punta a nulla è inutile (pericoloso) continuare l'esecuzione.

Ciao.
Title: Re: come funziona void
Post by: leo72 on Dec 21, 2013, 08:26 pm

Ora non ricordo l'ordine dei dati messi nello stack, ma anche l'indirizzo di ritorno deve stare nello stack, diversamente la funzione non saprebbe l'indirizzo da eseguire al termine della funzione stessa.

Come primo dato nello stack, quindi quello che si trova "sotto" a tutti quelli che poi saranno salvati dalla funzione stessa, c'è l'indirizzo dell'istruzione successiva a quella del salto. Una volta che la CPU trova l'istruzione RET, automaticamente preleva dallo stack il suddetto indirizzo, lo mette nel PR e poi prosegue ad eseguire il codice da quel punto.
Title: Re: come funziona void
Post by: nid69ita on Dec 22, 2013, 12:01 am

...chissà perché le funzioni C mi sembrano molto più naturali rispetto a quelle del GWBasic.

Perchè il GWBasic è una porcheria, il Basic già sul PDP11 era meglio di quel dialetto schifoso della M$.   $)
Per fortuna poi in Visual Studio han fatto un dialetto Basic un pò più serio e strutturato.    :D

P.S. l'avete visto lo SmallBasic della MS per insegnare ai bambini? E' carino, ricorda un pò il GWBasic.
http://smallbasic.com/ (http://smallbasic.com/)
Title: Re: come funziona void
Post by: leo72 on Dec 22, 2013, 12:14 am
Il GWBASIC, all'epoca, non era un bruttissimo BASIC. Era leeeento, ma nel complesso semplificava tante cose, come la gesione del suono e della grafica. Poi era molto organizzato per l'accesso ai file.

Aveva le pecche tipiche dei BASIC, insomma. Certo, se lo paragoni a linguaggi tipo il Pascal, era osceno. Ma devi pensare che il BASIC era nato per insegnare la programmazione anche ai principianti: "Beginner's All-purpose Symbolic Instruction Code"
Title: Re: come funziona void
Post by: Etemenanki on Dec 22, 2013, 09:40 am
Sara' per quello che persino un "coccio" come il sottoscritto era riuscito ad impararlo usando solo gli help ed il manuale :P

E' vero, linguaggi come il C e seguenti sono piu evoluti e permettono molto di piu in termini di funzionalita', ma non sono altrettanto "facili" da capire a livello intuitivo ... poi certo dipende da quanto uno lo usa, se ci stai tutto il giorno, e' piu semplice alla fine che ti rimanga in mente di piu, se ti capita di usarlo una volta al mese, un po meno :P XD
Title: Re: come funziona void
Post by: paulus1969 on Dec 22, 2013, 09:56 am
Anche il Quick Basic era carino, c'era una versione leggera nel MS-DOS e poi la versione per sviluppare, ho fatto tantissime cose con il QB45.
Pochi giorni fa ho installato il QB6... creato da sviluppatori indipendenti, riprende il QB45.
Title: Re: come funziona void
Post by: Maurotec on Dec 22, 2013, 11:20 am
@paulus1969
Si tratta di programma per android o anche per GNU/Linux?

No sai magari un link per dargli uno sguardo di strisciooo, please.

@Etem
Si può dire benissimo il contrario. Cioè, il liguaggio Basic attuale e quello del GWBasic sono più evoluti rispetto al C.
Il è un linguaggio nudo e crudo molto vicino all'hardware, dove tutta le responsabilità è caricata sul programmatore che deve curare tutto nel dettaglio. Il basic come linguaggio interpretato potrebbe permettersi certi lussi che il C o C++ non possono permettersi.

Il C/C++ è difficile perché per mantenere la potenziale efficienza, quasi tutto viene lasciato decidere al programmatore, che si trova con a che fare con una flessibilità che può essere giudicata eccessiva fino al momento in cui hai la necessità di modificare il comportamento di default.

In sostanza, la flessibilità introduce complessità e la semplificazione introduce rigidezza.

Ciao.
Title: Re: come funziona void
Post by: nid69ita on Dec 22, 2013, 11:30 am

Il C/C++ è difficile perché per mantenere la potenziale efficienza, quasi tutto viene lasciato decidere al programmatore, che si trova con a che fare con una flessibilità che può essere giudicata eccessiva fino al momento in cui hai la necessità di modificare il comportamento di default.
In sostanza, la flessibilità introduce complessità e la semplificazione introduce rigidezza.


Quotone. Mi capitò anni fà di essere mandato a sostituire un insegnante ad un corso di C presso un cliente che faceva rilevazioni meteologiche e relativi grafici. I corsisti si lamentavano perchè lavoravano in Basic e dalla sede principale gli avevano detto che il C era un linguaggio potentissimo, meglio del Basic. L'insegnante precedente non sapeva che dire. Al che gli feci telefonare alla sede principale e scoprimmo che quei furboni avevano comprato delle librerie in C che facevano pure la birra e che senza di quelle i lori programmi di grafica (poi dei grafici belli ma mica chissà che) non facevano una cippa di niente. Al che gli presentai il C per quel che è, come detto da @Mauro.  Un linguaggio a basso livello, potente perchè permette al programmatore di avere il controllo su tutto. Un linguaggio che permette di sviluppare S.O. o anche altri linguaggi.
Cosa che in Basic o Pascal non potresti fare.
Title: Re: come funziona void
Post by: gpb01 on Dec 22, 2013, 11:34 am

Cosa che in Basic o Pascal non potresti fare.


... e questa dove l'avresti letta ???  :smiley-eek: :smiley-eek: :smiley-eek:

Ma ... l'hai mai usato un vero compilatore Pascal ???  ]:D ]:D ]:D

Guglielmo

P.S. : E ... Turbo Basic della Borland ai bei tempi ???  ]:D ]:D ]:D
Title: Re: come funziona void
Post by: PaoloP on Dec 22, 2013, 11:38 am

Un linguaggio a basso livello...


Il C è un linguaggio ad alto livello.  Qualcuno lo definisce a medio livello.
Comunque un linguaggio a basso livello è l'Assembly.
Title: Re: come funziona void
Post by: nid69ita on Dec 22, 2013, 12:31 pm


Un linguaggio a basso livello...

Il C è un linguaggio ad alto livello.  Qualcuno lo definisce a medio livello.
Comunque un linguaggio a basso livello è l'Assembly.


Questione di termini. Per me (ovvio, opinione personale) il C è a basso livello o medio, assembler a bassissimo (quasi livello macchina).  Questo per differenziare nella mia visione Asm, C e gli altri linguaggi.

@Guglielmo, bellissimo il Turbo Pascal. L'ho adorato.  
Non mi risultano S.O. scritti in Pascal. Ne sai uno ?  :smiley-eek-blue:
Title: Re: come funziona void
Post by: gpb01 on Dec 22, 2013, 01:45 pm
@nid : che una cosa non sia stata fatta non significa, come tu affermavi, che non possa essere fatta ...

Premesso questo ... dai un'occhiata QUI (http://wiki.freepascal.org/Operating_Systems_written_in_FPC)   ]:D

Oltre a Turbo Pascal, che era ottimo, t'assicuro che anche Turbo Basic generava un codice ben ottimizzato, compatto e veloce !

Oggi giorno,  PowerBasic (http://www.powerbasic.com) è in grado di generare puro codice macchina (senza libreria di RunTime) estremamente ottimizzato e ... si riesce a scriverci veramente di tutto !

Guglielmo
Title: Re: come funziona void
Post by: nid69ita on Dec 22, 2013, 02:08 pm
Da quel che ho letto perciò il primo Mac OS era in Pascal mentre ora Mac OS X è in Objective C, giusto ?
Title: Re: come funziona void
Post by: Etemenanki on Dec 22, 2013, 02:51 pm

P.S. : E ... Turbo Basic della Borland ai bei tempi ???  ]:D ]:D ]:D


E' il primo basic "serio" che avevo provato su un PC ... cioe', il primo primo (su PC) era il "rombasic" dei vecchi IBM, ma quello meglio lasciarlo perdere (ancora mi ricordo il messaggio "No system disk - Starting with ROM-Basic" in tremolanti lettere verdine sugli M24 :P XD) ... ed il primo primo primo (in assoluto) era il basic dell'Atari720 :P
Title: Re: come funziona void
Post by: gpb01 on Dec 22, 2013, 03:21 pm

Da quel che ho letto perciò il primo Mac OS era in Pascal mentre ora Mac OS X è in Objective C, giusto ?


... probabilmente ma ...non solo. Svariate parte a basso livello (driver e cose simili) saranno ancora scritte in assembler ;)

Guglielmo
Title: Re: come funziona void
Post by: paulus1969 on Dec 22, 2013, 03:59 pm

@paulus1969
Si tratta di programma per android o anche per GNU/Linux?

No sai magari un link per dargli uno sguardo di strisciooo, please.




Eccolo qui
http://www.qb64.net/ (http://www.qb64.net/)
Windows, Linux, Mac, Android
Title: Re: come funziona void
Post by: leo72 on Dec 22, 2013, 11:01 pm

Questione di termini. Per me (ovvio, opinione personale) il C è a basso livello o medio, assembler a bassissimo (quasi livello macchina).  Questo per differenziare nella mia visione Asm, C e gli altri linguaggi.

Concordo.
Title: Re: come funziona void
Post by: leo72 on Dec 22, 2013, 11:02 pm

@Guglielmo, bellissimo il Turbo Pascal. L'ho adorato.  

Alle superiori studiai il Turbo Pascal 3.0 della Borland. A casa ho ancora il libro di testo  :D
Title: Re: come funziona void
Post by: nid69ita on Dec 22, 2013, 11:06 pm


@Guglielmo, bellissimo il Turbo Pascal. L'ho adorato.  

Alle superiori studiai il Turbo Pascal 3.0 della Borland. A casa ho ancora il libro di testo  :D


Siamo andati OT, anzi siamo in modalità REMEMBER.  Ehh, la vecchiaia   :smiley-mr-green:
Title: Re: come funziona void
Post by: leo72 on Dec 22, 2013, 11:09 pm
Sì siamo OT ...  ;)

PS:
non è vecchiaia, è esperienza!  ;)