NGI.Home > Forum
  EOLO HOME  OFFERTE INTERNET WIRELESS EOLO  FORMULA ADSL
   
   
WEBMAIL
   
 
  > Register  
  > FAQ  
  > Members List  
 
  > Calendar  
  > Today's Posts  
   
 

Go Back   NGI Forum > Tech & Tech > Developer's Zone

Reply
 
Thread Tools Rate Thread
Old 9th December 2010, 11:14   #1
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,478
[Impariamo il C] Lezione 5

Buongiorno.

Prosegue il corso collaborativo di programmazione.

Riassunto delle puntate precedenti:
  1. installazione dell'IDE, cenni di architettura degli elaboratori
  2. sintassi del C, programmazione strutturata
  3. ancora sulla sintassi, i tipi di dato, le variabili
  4. variabili parte seconda: gli array
In questo capitolo:
  • le funzioni
  • un nuovo sguardo sul main

Le funzioni

Ripartiamo ancora una volta dal nostro hello world.

Code:
void main()
{
  printf("Hello World!\n");
  system("pause");
}
Ormai conosciamo quasi tutto il significato di questo codice: sia come viene dichiarato il main (e il suo scopo), le stringhe, i segni di punteggiatura, le graffe, ecc.

Rimane un solo argomento non trattato: le funzioni.

printf e system (ma anche il main stesso) sono delle funzioni. Vi ricordate cosa sono le funzioni in matematica? Formalmente sono delle regole, delle leggi, delle indicazioni per mettere in relazione elementi di un insieme con quelli di un altro.



In questo esempio, la funzione f mette in relazione 1 con A, 2 con C e 3 con D.

Le funzioni possono essere arbitrarie come in questo caso, oppure avere comportamenti pił regolari (come quelle che siamo abituati a trattare). Per fare un esempio, potremmo avere una funzione chiamata successore tale che, preso un qualsiasi numero intero in ingresso, lo mette in relazione con il suo successore:



Come implementare una funzione del genere in C? Una prima strada, ingenua, potrebbe essere quella di fare un programma di questo tipo (pseudocodice):

Code:
main {   

   se ( dato_in_ingresso č 1 ) allora successore = 2
   se ( dato_in_ingresso č 2 ) allora successore = 3
   se ( dato_in_ingresso č 3 ) allora successore = 4
   ...

}
Salta subito agli occhi un problemino di fondo di questo approccio: enumerare tutti i casi č improponibile!

In informatica si utilizza un altro approccio, di natura induttiva: si progetta un algoritmo risolvente che funzioni per qualsiasi input e ritorni un output coerente. Il modo pił elegante per realizzare questo č creare una funzione (pseudocodice):

Code:
crea nuova funzione "successore" 
input X: numero intero 
output Y: numero intero 
{
    Y = X + 1
    ritorna Y
}
Abbiamo gią anticipato nelle scorse lezioni che la sintassi del C traduce questo pseudocodice in maniera leggermente diversa. Ecco come:

Code:
int successore( int X ) {
    int Y;
    Y = X+1;
    return Y;
}
Poiché la funzione ritorna un valore (di un qualsiasi tipo di dato che abbiamo visto nelle due lezioni precedenti, anche void) il compilatore vuole che noi gli si riservi un blocco di memoria. Ecco dunque che la funzione inizia dichiarando il tipo del valore di ritorno.

La seconda cosa da dichiarare č il nome delle funzione.

La terza sono i parametri in ingresso: quali dati utilizza la mia funzione per elaborare? In questo caso, sappiamo che vogliamo il successore di un numero intero, quindi dichiareremo la funzione con un solo parametro intero. I parametri si mettono tra parentesi tonde e possono essere in numero arbitrario. Si osservi che non abbiamo scritto

Code:
int successore( int ) {
...
ma abbiamo specificato anche il nome di una variabile

Code:
int successore( int X ) {
...
Perché? perché noi vogliamo poter utilizzare un qualsiasi valore arbitrario passato alla funzione, senza conoscerlo in anticipo. Dunque, nelle parentesi, avvengono delle vere e proprie dichiarazioni di variabili.

Attenzione ora. Le variabili dichiarate all'interno delle funzioni sono utilizzabili solo dentro il corpo delle funzioni: il main (e tutte le altre funzioni) non possono utilizzarle. Questa "visibilitą" delle variabili č detta scopo e va immaginata come delle vere e proprie strutture a matrioska: una variabile dichiarata dentro una matrioska pił piccola non č visibile da quella pił grande. Vale invece il viceversa: se dichiaro una variabile prima della funzione, la potrņ utilizzare.


Abbiamo gią anticipato che le funzioni ritornano un valore. Ciņ avviene con l'istruzione return, che si occupa anche di interrompere l'esecuzione della funzione e restituire il controllo al chiamante (ad esempio il main).

Code:
int successore( int X ) {
    int Y;
    Y = X+1;
    return Y;
}
Dunque, traduciamo in linguaggio naturale questo codice C:
  • dichiariamo una funzione che ritorna un numero intero chiamata successore
  • questa funzione accetta un (e un solo) parametro in ingresso, di tipo intero che, alla chiamata di funzione, verrą inserito nella variabile X
  • dichiariamo un'altra variabile Y
  • mettiamo in Y il valore X+1
  • ritorniamo Y e chiudiamo l'esecuzione della funzione

Riprendendo in mano le funzioni viste nell'hello world, ora intuiamo che printf e system accettano come parametri in ingresso delle stringhe. In realtą, la printf č pił potente di cosģ: accetta anche altri parametri, che consentono di formattare l'output a video. Inoltre, entrambe le funzioni ritornano dei valori. Torneremo su di esse in seguito.


Un nuovo sguardo sul main

Chiaramente, in funzioni dichiarate con void non dobbiamo restituire nulla; questo č il caso del nostro main dell'hello world. Tuttavia, la sintassi corretta del main č questa:

Code:
int main( int argc, char* argv[] )  {
...
}
Vediamo che il main deve restituire un intero (ormai lo sapevate gią ) e riceve due parametri in ingresso. Di questi parametri parleremo pił avanti (perché ancora non sapete quell'asterisco cosa significa), ma se avete mai utilizzato una console intuite gią che si riferiscono ai parametri che si possono passare ai programmi.

Ora vediamo come scrivere un programma che, letto un numero dall'utente, ne stampa il successore.

Code:
int successore( int X ) {
    return X+1;
}

int main( int argc, char* argv[] ) {

   /* dichiaro le variabili che userņ */
   int valore;
   int ritorno;

   /* leggo input */
   printf( "Inserire un numero intero: " );
   scanf ( "%d" , &valore );

   /* stampo output */
   ritorno = successore( valore );
   printf( "Il suo successore č: " );
   printf( "%d", ritorno );

   /* fine: inseriamo una pausa e poi ritorniamo zero (=tutto okay) :) */
   system( "pause" );
   return 0;   
}
Seguono quattro osservazioni.

Osservazione 1: la funzione deve essere dichiarata PRIMA del corpo principale, sennņ il main non sa di cosa stiamo parlando ("successore??! che č??") e il compilatore ci da errore.

Osservazione 2: nella funzione successore non ho dichiarato una variabile Y di appoggio. In effetti č inutile, possiamo ritornare direttamente il risultato se la funzione č semplice: risparmiamo memoria.

Osservazione 3: nel main ho inserito dei commenti tramite /* ... */ . E' buona norma commentare sempre il proprio codice, perché qualunque sviluppatore puņ confermarvi quanto sia difficile rimettere mano al proprio codice (o, peggio, a quello altrui) se non č stato adeguatamente commentato. Altre buone regole sono l'indentazione e l'uso di nomi di variabili significativi (e non cose tipo pippo = pluto + 1).

Osservazione 4: come vedete, sia scanf che printf hanno richiesto l'uso di %d, mentre nell'esempio precedente usavamo %s. Sarą spiegato in futuro il motivo, ma possiamo anticipare che č legato al fatto che prima manipolavamo stringhe e ora dei numeri (decimals); entrambe le funzioni, per lavorare, han bisogno di sapere su che tipi di dato stanno agendo.




L'esercitatore Kaehell vi fornirą ora dei succosi esercizi per testare la vostra comprensione della prima tranche dell'argomento funzioni.
Attached Images
File Type: png successore.png (15.7 KB, 279 views)
__________________
Lode a Bacco, in saecula saeculorum.
Emergent

Last edited by Arėsius; 9th December 2010 at 13:03.
Arėsius is offline   Reply With Quote
Old 9th December 2010, 11:34   #2
uizz
Registered User
 
uizz's Avatar
 
Join Date: Jan 2010
Posts: 513
Wow veramente chiaro e puntuale, l'inizio puņ spaventare ma dal primo esempio in poi scorre tutto liscio^^
Ti volevo chiedere: ma quindi le funzioni vanno scritte prima del main? Perché in java mi sembra si possa fare:

funzione1(){
bla bla;
}

main(){
funzione1();
funzione2();
}

funzione2(){
bau bau;
}
uizz is offline   Reply With Quote
Old 9th December 2010, 11:39   #3
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,478
sģ, in C vanno scritte prima. come vedremo verso la fine del corso, puoi aggirare il problema tramite l'uso dei prototipi, che iniziano a dichiarare le funzioni prima di specificarne il corpo:

Code:
/* prototipo */
void funzione2();

main() {
   funzione2();
} 

void funzione2() {
   bau bau;
}
__________________
Lode a Bacco, in saecula saeculorum.
Emergent
Arėsius is offline   Reply With Quote
Old 9th December 2010, 11:54   #4
uizz
Registered User
 
uizz's Avatar
 
Join Date: Jan 2010
Posts: 513
Ah ecco grazie, li avevo gią visti ma non ne avevo compreso l'utilitą
uizz is offline   Reply With Quote
Old 9th December 2010, 13:07   #5
nanomad
Dietro le sbarre
 
nanomad's Avatar
 
Join Date: Apr 2005
Location: Papia (olim Ticinum)
Posts: 5,221
La lezione č stata caricata sul wiki
__________________
Rivuoi i video nel forum? Usa questa estensione (chrome)
Source & firefox version
"(...) the three great virtues of a programmer: laziness, impatience, and hubris." -- LarryWall

Last edited by nanomad; 9th December 2010 at 17:06.
nanomad is offline   Reply With Quote
Old 9th December 2010, 15:41   #6
Pier4R
Ex falso quodlibet
 
Pier4R's Avatar
 
Join Date: Jul 2004
Location: equgpbc.r2.Frisia
Posts: 18,664
mi iscrivo, anche in object pascal ci sono i metodi "virtuali", non li avevo ben collegati a C. Pascal e C sembran simili (anche se preferisco pascal come primo amore), chissą se gli * (puntatori giusto?) si comportano come i ^ in Pascal.
__________________
Ngi the e.FlameeXperience • • • .Fe • • • ! • • • ngi.agorą@twitter (sottoscrivi per essere incluso)
You must play online: warSow • • • EnemyTerritory + etpro • • • quake 4 + q4max & quake 3 + cpma & quakelive • • • Teeworlds! • • • hoi2series

Ringrazio i grammar nazi che mi fanno comprendere gli errori ; my.IL
; lettere porno
Pier4R is offline   Reply With Quote
Old 9th December 2010, 16:53   #7
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,478
non so in object pascal cosa siano i metodi virtuali; in C non ci sono perché... non esistono i metodi (niente classi).

In C++ esistono i metodi virtuali e hanno a che fare coi problemi di ereditarietą, o nel caso delle funzioni "virtuali pure" con le classi astratte; non credo ne parleremo mai su questi schermi

edit: comunque Pascal e C sono strettissimi parenti, essendo entrambi linguaggi imperativi.
__________________
Lode a Bacco, in saecula saeculorum.
Emergent

Last edited by Arėsius; 9th December 2010 at 17:41.
Arėsius is offline   Reply With Quote
Old 9th December 2010, 18:55   #8
Knu
(\/) (;,,;) (\/)
 
Knu's Avatar
 
Join Date: Jan 2009
Location: Mantova/Verona/Brescia
Posts: 5,704
vedo un'ecatombe di studenti o sbaglio? 6 reply
__________________
· My Steam ·
Knu is offline   Reply With Quote
Old 9th December 2010, 21:38   #9
Kaehell
l33t school
 
Kaehell's Avatar
 
Join Date: Mar 2008
Location: Zģria
Posts: 14,633
scusate ma sono infognato nella programmazione e ho poco tempo per seguire. Sono gią finiti gli studenti?
__________________
"...the three great virtues of a programmer: laziness, impatience, and hubris." - Larry Wall
The e.Ngineering Xperience ••
BattleNet - Kaeh#2263 || Diablo3 - Kaeh
Kaehell is offline   Reply With Quote
Old 9th December 2010, 22:11   #10
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,478
Quote:
Originally Posted by Knu View Post
vedo un'ecatombe di studenti o sbaglio? 6 reply
ho la stessa sensazione.

pensavo succedesse dopo, tipo alla prima malloc
__________________
Lode a Bacco, in saecula saeculorum.
Emergent
Arėsius is offline   Reply With Quote
Old 9th December 2010, 22:51   #11
uizz
Registered User
 
uizz's Avatar
 
Join Date: Jan 2010
Posts: 513
Potrebbe aiutare una lista dei maggiori utilizzi del C...perché sinceramente sto iniziando a chiedermi anch'io in che ambiti lo potrei usare...app per linux? app per windows? driver? boh
uizz is offline   Reply With Quote
Old 9th December 2010, 23:09   #12
[En][gma]
Registered User
 
[En][gma]'s Avatar
 
Join Date: Dec 2001
Posts: 2,954
eiei, io ci sarņ sempre! tič!
solo che la settimana scorsa ero in ferie e pił tempo per dibattere qui...

anzi, per ora mi sembra tutto abbastanza chiaro....ora non ho voglia di mettermi a sperimentare a caso...
aspetto l'esercizio per casa e poi si vedrą
__________________
.: NoS - Nitrous Oxide System :.
[En][gma] is offline   Reply With Quote
Old 9th December 2010, 23:16   #13
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,478
@Kaehell, se sei in sbattimento mi invento un esercizio io per questa lezione. La calcolatrice la fai al prox giro okay?

@uizz. in realtą non stiamo guardando il C al fine di usarlo sul serio. applicazioni utili le hai gią dette: app per qualsiasi sistema operativo (il codice che vedremo sarą interamente cross platform e portabile), driver, piccole applicazioni di servizio.

ad esempio, una volta mi ero programmato un client di posta per ravanare nella posta alla ricerca di messaggi di un certo tipo e, nel caso ci fossero, far effettuare certe azioni al computer (leggi mandarmi sms ).

il punto č che una volta che consoci il C, poi passare a PHP/Javascript č un attimo. inoltre, verrebbe naturale alla fine del corso sfociare a C++ o Java. insomma, č un punto di partenza, non di arrivo.
__________________
Lode a Bacco, in saecula saeculorum.
Emergent

Last edited by Arėsius; 10th December 2010 at 00:18.
Arėsius is offline   Reply With Quote
Old 9th December 2010, 23:21   #14
[En][gma]
Registered User
 
[En][gma]'s Avatar
 
Join Date: Dec 2001
Posts: 2,954
Piccolo OT:
un esempio o una semplice infarinatura sui driver mi piacerebbe assai!
e finito il corso passare a un'infarinatura generale o anche qualcosa di pił avanzato su Java (specie per poi orientarmi alle applicazioni su cellulari...) sarebbe altrettanto bello per me.
__________________
.: NoS - Nitrous Oxide System :.
[En][gma] is offline   Reply With Quote
Old 10th December 2010, 00:30   #15
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,478
propongo un esercizio per gli aficionados.

scrivere un programma che legge dall'utente due numeri (x1 e x2), li passa ad una funzione chiamata somma_dei_prodotti_piu_uno che implementa questa funzione:

y = x1*x1+x2*x2 + 1

Il valore di ritorno dev'essere stampato a video.


Provare questo codice con
x1=16777216
x2=16777216
e provare a spiegare il risultato.
__________________
Lode a Bacco, in saecula saeculorum.
Emergent
Arėsius is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 04:42.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright 1998-2014 by NGI SpA