Repository 32bit  Forum
Repository 64bit  Wiki

domanda sulla programmazione in C

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

domanda sulla programmazione in C

Messaggioda dark0s » sab ott 18, 2008 1:58

Vorrei fare una domanda riguardo il linguaggio C.
Io ho sempre proghrammato come un principiante, ovvero tutto il codice sorgente del mio programma l'ho sempre inserito in un file .c.
Però a quanto vedo i professionisti e per i progetti di grandi dimensioni si divide il codice in un file .h ed in un file .c.
Ad esempio se il mio programma è miprogramma.c con il seguente contenuto:

#include libreria1
#include libreria2
#include libreria3

void funzione 1 {
...
...
}

void funzione 2 {
...
...
}

int main() {

...
...

}

come devo suddividere il file?
dark0s
Linux 2.6
Linux 2.6
 
Messaggi: 556
Iscritto il: lun gen 10, 2005 0:00

Re: domanda sulla programmazione in C

Messaggioda targzeta » sab ott 18, 2008 8:45

La suddivisione in più file viene fatta per comodità e non per necessità. Questo implica il ricadere nel personale, a me può sembrare comoda una suddivisione laddove a te può sembrare comoda un altra.
Il principio di base applicato è comunque il riutilizzo. Si divide il programma su più file ognuno dei quali contiene una collezione di funzioni concettualmente legate da una logica personale. Questo permette il riutilizzo di tale file in un altro programma. Il file '.c' diventa a tutti gli effetti una libreria, che per un motivo o per un altro tendiamo a non rilasciarla come tale, ma che linkiamo direttamente al codice del nostro programma. La creazione dei file header ('.h') diventa poi una evoluzione naturale del concetto.

Un esempio:
- Se dobbiamo scrivere un programma che effettua delle operazioni su matrici, allora viene spontaneo creare un file chiamato 'matrici.c' dove inseriremo tutte le funzioni che implementano queste operazioni (trasposta, inversa, calcolo del determinante...se possibile, etc.etc...). Un altro file potrebbe chiamarsi 'parser.c' in cui implementiamo le funzioni che controllano l'input dell'utente.
A questo punto, il main viene inserito in un file chiamato 'main.c' e si limita a richiamare, passando in maniera corretta i parametri, le funzioni definite nei due file 'matrici.c' e 'parser.c'. Questo modo di programmare rende il nostro codice riutilizzabile, infatti il 'main.c' è il cuore del nostro programma che gestisce le operazioni matriciali, è piccolo e ci permette, in breve tempo, di capire come funziona il programma. Mentre i file 'matrici.c' e 'parser.c', pur essendo parte essenziale del nostro programma, non dipendono da esso, sono moduli a se stanti che possiamo inserire in un altro programma.
Per poter invocare le funzioni definite nei file 'matrici.c' e 'parser.c' in maniera corretta, il nostro main deve essere a conoscenza della loro dichiarazione. Ed ecco allora che entrano in gioco i file header (i '.h'), che contengono almeno le dichiarazioni di tutte le funzioni "pubbliche" definite all'interno dei file 'matrici.c' e 'parser.c'. Dico "pubbliche", perchè può succedere che ci siano funziono 'static', ovvero che non sono utili in termini di "interfaccia" verso l'esterno, ma servono solamente alle funzioni definite nel file 'matrici.c' e 'parser.c'. Ovviamente oltre alla dichiarazione delle funzioni "pubbliche", nel file header uno ci deve inserire anche le definizioni delle macro utilizzate dalle funzioni.

Quando si scrive un file '.c' si deve sempre tenere a mente il possibile riuso, e come esso deve essere riutilizzato da vari programmi. Bene, il modo con cui il nostro file deve essere riutilizzato rappresenta l'interfaccia del nostro programma, e l'interfaccia viene implementata dal file header '.h'.

Spina
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà
Avatar utente
targzeta
Iper Master
Iper Master
 
Messaggi: 6200
Iscritto il: gio nov 03, 2005 14:05
Località: Carpignano Sal. (LE) <-> Pisa
Nome Cognome: Emanuele Tomasi
Slackware: current
Kernel: latest stable
Desktop: IceWM

Re: domanda sulla programmazione in C

Messaggioda 414N » sab ott 18, 2008 8:54

dark0s ha scritto:Vorrei fare una domanda riguardo il linguaggio C.
Io ho sempre proghrammato come un principiante, ovvero tutto il codice sorgente del mio programma l'ho sempre inserito in un file .c.
Però a quanto vedo i professionisti e per i progetti di grandi dimensioni si divide il codice in un file .h ed in un file .c.

Veramente si divide in più file header (.h) e più file sorgenti (.c), quando il progetto è di grandi dimensioni.
dark0s ha scritto:Ad esempio se il mio programma è miprogramma.c con il seguente contenuto:
Codice: Seleziona tutto
#include libreria1
#include libreria2
#include libreria3

void funzione 1 {
...
...
}

void funzione 2 {
...
...
}

int main() {

...
...

}

come devo suddividere il file?

Puoi fare una roba simile:
  • un file header contenente le librerie da includere, le varie definizioni di costanti/macro/tipo, i prototipi delle funzioni che vuoi divididere su più file:
    Codice: Seleziona tutto
    #include libreria1
    #include libreria2
    #include libreria3
    #define blabla 23213213

    typedef struct ambarabà {
     ...
    };

    void funzione 1 (args);
    ...
  • Uno o più file sorgenti (.c) contenenti le varie implementazioni del caso, i quali devono includere il file header da te appena definito (es: #include "mydefs.h"). A seconda della dimensione del corpo delle funzioni e della loro correlazione logica (dati che trattano, etc.), potresti mantenere tutto sempre su un file, oppure su 2 o più. Il C dà molta libertà in questo senso e sta allo sviluppatore scegliere il giusto compromesso tra numero di file e implementazioni di funzioni. In altri linguaggi (come Java), lo sviluppatore è forzato a creare un file per ogni classe pubblica che crea.

Azz, secondo! :)
Avatar utente
414N
Iper Master
Iper Master
 
Messaggi: 2884
Iscritto il: mer feb 13, 2008 16:19
Località: Bulagna
Slackware: 14.0 (x64)
Kernel: 3.2.29
Desktop: LXDE

Re: domanda sulla programmazione in C

Messaggioda Blizzard » sab ott 18, 2008 9:40

se non ti è stato detto nelle precedenti risposte...
il preprocessore C effettua più o meno solo delle sostituzioni di stringhe.
La direttiva #include sostituisce al posto della direttiva stessa il file passato come argomento.

Ergo il seguente strano codice compila e funziona anche bene

ciclo.c
Codice: Seleziona tutto
#include <stdio.h>

int main()
{
  int a=0;
 
  #include "ciclo.h"
   printf("%d",a);
  }
}


ciclo.h
Codice: Seleziona tutto
for(a=0;a<10;++a){



In definitiva, dato che il compilatore C deve necessariamente avere il prototipo di una funzione prima di utilizzarla, si utilizzano le include per fare il merge dei prototipi prima della funzione che li utilizza.
Questo porta, infatti, a spiacevoli conseguenze come definizioni multiple qualora non si adottino particolari accorgimenti e i file vengano inclusi in più parti.

EX:

a.h
Codice: Seleziona tutto
int a();


b.h
Codice: Seleziona tutto
#include "a.h"
float b();


main.c
Codice: Seleziona tutto
#include "a.h"
#include "b.h"

int main()
{
return 0;
}


Errore di definizione multipla!!!!!!
il file risultante dopo il preprocessing sarà
Codice: Seleziona tutto

int a();

int a();   //NOOOOOOOOOOO
float b();

int main()
{
return 0;
}


Ovviamente qualche compilatore potrebbe tentare un salvataggio di emergenza :)

Per fare le cose bene ed evitare inclusioni multiple utilizza il proverbiale trucchetto (sempre sfruttando il preprocessore!)

file a.h
Codice: Seleziona tutto
#ifndef _A_
#define _A_

int a();

#endif


:thumbright:

Gio
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: domanda sulla programmazione in C

Messaggioda Blizzard » sab ott 18, 2008 9:45

Blizzard ha scritto:Ergo il seguente strano codice compila e funziona anche bene

ciclo.c

Codice: Seleziona tutto
#include <stdio.h>

int main()
{
int a=0;

#include "ciclo.h"
printf("%d",a);
}
}



ciclo.h

Codice: Seleziona tutto
for(a=0;a<10;++a){



Dimenticavo!
Se un giorno ti trovo a fare una cosa simile ti "uccido" :D (e mi fai venire pure i rimorsi)
Non solo è genericamente una cosa mostruosa ma avrai problemoni anche se commetti un errore e il compilatore comincia a dirti che si trova da "QUALCHE PARTE" :P

Funziona bene ma è un esempio ok?
;)
Avatar utente
Blizzard
Master
Master
 
Messaggi: 1509
Iscritto il: mar gen 02, 2007 22:53
Nome Cognome: Giovanni Santostefano
Slackware: 12.2
Kernel: 2.6.27.7-smp
Desktop: Fluxbox

Re: domanda sulla programmazione in C

Messaggioda Mario Vanoni » sab ott 18, 2008 15:16

Tutte le routine riusabili:

gcc -c routine.c
ar rv /usr/lib/libvanoni.a routine.o


Nei progammi che uso:

gcc -s -o programma programma.c -lvanoni

spesso, e lo preferisco

gcc -O2 -s -static -o programma programma.c -lvanoni

esiste anche -Os al posto di -O2, ma non mi convince.


Nota a parte:
sia nelle routine che nei programmi uso la variabile
"@(#) ... ", modificata specificamente per gcc(1),
cosi` con what(1) vedo le versioni,
se datate correttamente nel codice sorgente,
e quando sono state compilate, programma _e_ routine.


PS Uso what(1) proveniente da NetBSD del 1999.
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 2 ospiti

cron