Newsgroup: it.comp.lang.c
Titolo: dividere programma su piu file

Salve,
per mia ignoranza, ho scritto un programma di circa 1200 righe in un 
unico file.
Come potete ben immaginare vorrei dividerlo su piu file, ma ho alcune 
domande da porvi:
una volta diviso il programma in moduli, e lasciato il main all'interno 
del file "principale", i prototipi e le funzioni degli altri moduli le 
salvo in file .h che includerò nel file principale?
ho varie struct e typedef, vanno in un file a parte o le lascio nel file 
  di ogni modulo che le utilizza?
Quale è la via migliore per "dividere" il programma?
Scusate le domande da principiante, ma avendo sempre scritto programmi 
di poco "conto", non mi sono mai preoccupato di come dividere il 
programma in piu file, nonostante abbia sempre seguito un approccio 
modulare per la stesura del mio programma.
Grazie!
Un saluto.
Gabriele

 Quale è la via migliore per "dividere" il programma?
Non esistono regole standard per come suddividere un programma in 
moduli, ma solo regole dettare dal buon senso e dall'esperienza.
In certe strutture queste regole diventano piu` o meno mandatorie per 
facilitare la gestione da parte di piu` progettisti e la rispondenza a 
regole di gestione e tracciabilita` delle modifiche.
Dalla mia esperienza, un programma di 1200 linee non e` un problema e 
puo` essere ancora gestito in un unico file, ma se vuoi fare un po` di 
esercizio ti consiglio alcune regole (derivate dalle esperienze fatte 
partecipando ad alcuni grossi progetti) che io normalmente adotto.  I 
nomi dei file sono scelti per meglio rappresentare la funzione.
main.c
file che contiene il main() eventuali funzioni di inizializzazione dei 
dati, dell'hardware e dei segnali ed infine il parsing degli argomenti 
o opzioni del programma.
dati.c
file che contiene le definizioni dei dati globali.
file1.c file2.c .....
uno o piu` files contenenti le funzioni per implementare il programma. 
  Ciascun file dovrebbe contenere funzioni omogenee, per esempio: 
I/O, allocazioni di memoria, gestione del tempo, algoritmo principale 
del programma ecc.
global.h
header file (da includere in tutti i file .c) con le definizioni dei 
tipi, le definizioni delle costanti e macro del preprocessore, le 
dichiarazioni (extern) dei dati e delle funzioni globali al programma.
File1.h file2.h ....
In casi particolari (programmi con un numero elevato di moduli) e` 
utile avere altri header file nel caso ve ne siano alcuni che 
esportano dati/funzioni solo verso pochi (1 o 2) altri moduli.
Oltre a questa suddivisione del programma in moduli ti suggerisco 
anche uno standard su come strutturare i file.  Piu` commenti 
inserisci meglio e`
/* Include di sistema */
#include <.....>
/* Include locali del programma */
#include "....."
/* definizioni di costanti/macro locali */
#define ZERO 0
/* definizione di tipi locali */
typedef unsigned long u32_t;
/* definizione dei dati locali (static) */
static int my_local_var;
/* prototipi delle funzioni locali (static) */
static int my_local_func(const char *text, int len);
/* funzioni statiche */
/* ogni funzione e` corredata da una descrizione della
funzionalita'. degli argomenti di ingresso/uscita e da
eventuali osservazioni */
static int my_local_func(const char *text, int len)
{
    ......
    return ZERO;
}
/* funzioni globali */
int main(int argc, char **argv)
{
    .......
    return ZERO;
}
/* fine del modulo */
-----------------------------------------
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >


Forse ti puo' aiutare anche farti una semplice domanda:
chi lavora con le funzioni di un certo file, che cosa deve saepre?
strutture, tipi di dato,protoripi..;
tutto questo va nell'header del file che mette a disposizione le sue
funzioni.
L'header e' come il libretto delle istruzioni che tu presenti a un
altro;
pensa di fare delle funzioni che un altro deve usare.
Gli devi dire come si chiamano, che dati usare per chiamarle, che cosa
si asepttano
di ritorno. Se inventi un tipo di dato, devi far sapere all'altro che
cosa e'.
ciao
davide

 Giovanni
Gabriele

 #include <file1.c>   ?
No ciascun file .c va compilato separatamente.  I vari moduli vanno 
poi linkati assieme.
Se ti interessa puoi trovare un esempio di programma (preprocessore C) 
diviso in moduli secondo le direttive descritte nel precedente post 
all'indirizzo 
http://giovanni.homelinux.net/cpp/
Il Makefile e` specifico per il GNU make, ma non dovrebbe essere 
difficile adattarlo ad altri ambienti.  Riuscivo a compilarlo 
tranquillamente su MSDOS ma non ho il Makefile.


 posso scrivere: #include <file1.c>   ?
Per fare cosa?
In un file C all'inizio si mettono gli #include per includere gli header
file (con estensione .h) di cui si ha bisogno.

 Giovanni
Grazie ancora!
Un saluto.
Gabriele

 con pochi file, non è cosa semplice da scrivere! :((
Il makefile presente su 
http://giovanni.homelinux.net/cpp/
 e` scritto 
per sfruttare al massimo le caratteristiche del GNU make e permettere 
di ricompilare, dopo ogni modifica, solo il minimo indispensabile. Per 
compilare il programma manualmente con un unico comando e` sufficiente:
$ gcc <opzioni di compilazione> main.c file1.c file2.c file3.c -o 
nome_eseguibile
oppure e` possibile compilare i singoli moduli:
$ gcc <opzioni di compilazione> -c main.c
$ gcc <opzioni di compilazione> -c file1.c
$ gcc <opzioni di compilazione> -c file2.c
$ gcc <opzioni di compilazione> -c file3.c
Ciascun file produce il corrispondente file .o e questi devono essere 
linkati assieme:
$ gcc main.o file1.o file2.o file3.o -o nome_eseguibile
Una versione semplificata del Makefile, per sfruttare i default del 
programma make, potrebbe essere:
##------------------------
CFLAGS  = <opzioni di compilazione>
LDFLAGS = <opzioni di link>
OBJECTS = <lista dei file .o>
all:	nome_eseguibile
nome_eseguibile:	$(OBJECTS)
$(OBJECTS):   <lista file .h>	## solo locali
##------------------------


 Giovanni
Un saluto.
Gabriele

 directory del makefile.
Sei sicuro che la linea inizi con un tab ? Perche'  se invece hai messo 
spazi non funzia (così  usano i makefile!).
Giorgio

 directory del makefile.
Gli oggetti NON devono essere eliminati se non quando vuoi fare 
pulizia completa.
$ make clean
Come ti ha gia` consigliato Giorgio verifica che la linea:
	$(RM) $(PROG) $(OBJS)
inizi con un tab altrimenti non funziona (ma dovrevve dare errore).
Verifica anche che la macro RM sia definita.  Non sricordo ma non e` 
un default.  Devi definire:
## il -f evita che dia errori se qualche file non esiste
RM = rm -f
