domanda sulla programmazione in C
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.
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
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?
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?
- targzeta
- Iper Master

- Messaggi: 6643
- Iscritto il: gio 3 nov 2005, 14:05
- Nome Cognome: Emanuele Tomasi
- Slackware: 64-current
- Kernel: latest stable
- Desktop: IceWM
- Località: Carpignano Sal. (LE) <-> Pisa
Re: domanda sulla programmazione in C
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
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
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
- 414N
- Iper Master

- Messaggi: 2924
- Iscritto il: mer 13 feb 2008, 16:19
- Slackware: 15.0
- Kernel: 5.15.19
- Desktop: KDE5
- Località: Bulagna
- Contatta:
Re: domanda sulla programmazione in C
Veramente si divide in più file header (.h) e più file sorgenti (.c), quando il progetto è di grandi dimensioni.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.
Puoi fare una roba simile:dark0s ha scritto: Ad esempio se il mio programma è miprogramma.c con il seguente contenuto:come devo suddividere il file?Codice: Seleziona tutto
#include libreria1 #include libreria2 #include libreria3 void funzione 1 { ... ... } void funzione 2 { ... ... } int main() { ... ... }
- 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.
- Blizzard
- Master

- Messaggi: 1509
- Iscritto il: mar 2 gen 2007, 22:53
- Nome Cognome: Giovanni Santostefano
- Slackware: 12.2
- Kernel: 2.6.27.7-smp
- Desktop: Fluxbox
- Contatta:
Re: domanda sulla programmazione in C
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
ciclo.h
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
b.h
main.c
Errore di definizione multipla!!!!!!
il file risultante dopo il preprocessing sarà
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
Gio
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);
}
}
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();
Codice: Seleziona tutto
#include "a.h"
float b();Codice: Seleziona tutto
#include "a.h"
#include "b.h"
int main()
{
return 0;
}
il file risultante dopo il preprocessing sarà
Codice: Seleziona tutto
int a();
int a(); //NOOOOOOOOOOO
float b();
int main()
{
return 0;
}
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
Gio
- Blizzard
- Master

- Messaggi: 1509
- Iscritto il: mar 2 gen 2007, 22:53
- Nome Cognome: Giovanni Santostefano
- Slackware: 12.2
- Kernel: 2.6.27.7-smp
- Desktop: Fluxbox
- Contatta:
Re: domanda sulla programmazione in C
Dimenticavo!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){
Se un giorno ti trovo a fare una cosa simile ti "uccido"
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?
-
Mario Vanoni
- Iper Master

- Messaggi: 3174
- Iscritto il: lun 3 set 2007, 21:20
- Nome Cognome: Mario Vanoni
- Slackware: 12.2
- Kernel: 3.0.4 statico
- Desktop: fluxbox/seamonkey
- Località: Cuasso al Monte (VA)
Re: domanda sulla programmazione in C
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.
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.
