Sto lavorando su un grande progetto in C, e voglio organizzarlo usando i file di interfaccia (.h) e di implementazione (.c), simili a molti linguaggi orientati agli oggetti come Objective -C o Java. Ho familiarità con la creazione di librerie statiche in C, ma penso che farlo per il mio progetto sia inutilmente complesso. Come posso implementare un paradigma di interfaccia/implementazione in ANSI C? Sto principalmente utilizzando GCC per la compilazione, ma sto puntando a una stretta aderenza a ANSI C e alla compatibilità cross-compiler. Grazie!Interfaccia/implementazione in ANSI C
risposta
Sembra che tu sei già fare la cosa giusta: buon codice C anche organizza interfacce in .h-files e le implementazioni in .c-files.
Esempio di file ah:
void f(int a);
Esempio file di AC:
#include "a.h"
static void helper(void) {...}
void f(int a) {... use helper()...}
Esempio di file main.c:
#include "a.h"
int main(void) { f(123); return 0; }
Si ottiene modularità perché helper-funzioni non sono dichiarati in le intestazioni in modo che gli altri moduli non ne siano a conoscenza (è possibile dichiararle nella parte superiore dello .c
file se vuoi). Questa modularità riduce il numero di ricompilazioni necessarie e riduce la quantità di che deve essere ricompilata. (Il collegamento al deve essere eseguito ogni volta). Si noti che se non si dichiarano le funzioni di aiuto nell'intestazione, si è già abbastanza sicuri, tuttavia avere il static
davanti a loro li nasconde anche da altri moduli durante il collegamento, quindi non c'è conflitto se più moduli utilizzano la stessa funzione di supporto -names.
Se si lavora solo con tipi primitivi, questo è tutto ciò che è necessario sapere e è possibile interrompere la lettura qui. Tuttavia, se il tuo modulo ha bisogno di lavorare con una struct, diventa un po 'più complicato.
problematico esempio intestazione b.h:
typedef struct Obj {
int data;
}*Obj;
Obj make(void);
void work(Obj o);
Il modulo vuole passare gli oggetti dentro e fuori. Il problema qui è che gli interni sono trapelati ad altri moduli che dipendono da questa intestazione. Se la rappresentazione viene modificata in float data
, tutti i moduli che utilizzano devono ricompilare. Un modo per risolvere questo problema è utilizzare solo void*
. Questo è il modo in cui molti programmi lo fanno. Tuttavia questo è ingombrante perché ogni funzione che riceve l'argomento void*
deve inoltrarla a Obj
. Un altro modo è quello di fare questo:
Header ch:
typedef struct Obj*Obj;
Obj make(void);
void work(Obj);
Attuazione cc:
#include "c.h"
typedef struct Obj {
int data;
}*Obj;
Il motivo per cui questo funziona è che Obj è un puntatore (al contrario di una struttura da valore/copy). Altri moduli che dipendono da questo modulo hanno solo bisogno di sapere che un puntatore viene passato dentro e fuori, non a cosa punta.
Grazie per la tua risposta chiara. Questo può essere fatto con un comando in GCC? Basta chiamare "gcc main.c" per ottenere un errore di simboli non definiti. – user2105505
Dovresti chiamare 'gcc -c nomefile.c' per ogni c-file. Ognuno di loro genera un file .o (modulo). Alla fine chiami 'gcc * .o' che li collega tutti insieme. Se hai cambiato solo 'b.c', allora deve solo essere ricompilato (' b.o') e tu dovrai riconnetterti. (i file c non modificati non devono essere nuovamente compilati) –
@ user2105505 inoltre, questo è normalmente automatizzato da un makefile. con questo è sufficiente digitare "make" sulla riga di comando e sceglierà quale c-file da ricompilare e quindi collegherà il programma insieme. –
È necessario leggere qualcosa su OOP con non OOL come http://www.cs.rit.edu/~ats/books/ooc.pdf. Ma, facendo questo non avrai mai una forte digitazione OOP.
Inoltre, così facendo ti farà impazzire;) –
Questo è un po 'esagerato ma avrai bisogno di una disciplina almeno forte (che potrebbe farti impazzire). –
"Mi sono divertito a scoprire che ANSI-C è un linguaggio orientato agli oggetti su vasta scala" - ha smesso di leggerlo. Divertente. Sì, si può SEMPLIFICARE i modelli OOP con uno sforzo MASSIVO ma questo è praticamente insensato e inefficiente, anche: in pratica sarebbe stato reinventare una ruota. Non c'è bisogno di schemi OO in C. C è praticamente un linguaggio di basso livello, forzare l'OO in esso provocherà solo problemi - ecco perché è stato inventato Obj-C. – specializt
Fatevi un favore e leggere C Interfaces and Implementations: Techniques for Creating Reusable Software
Ecco a repository of mine che contiene alcune librerie scritte in C utilizzando il modello di interfacce & implementazione descritto nel libro.
Stai parlando di OOP in C? –
No, sono fondamentalmente alla ricerca di un modo per separare le definizioni di funzione dai meccanismi interni di tali funzioni e anche un metodo per raggruppare funzioni correlate e tali insieme (come math.h, ad esempio). Non voglio utilizzare una libreria perché non riusciamo a riutilizzare le funzioni in altri programmi e potrebbe anche essere necessario apportare modifiche frequenti alla funzionalità. – user2105505
Rendi statica la funzione nel file .h, e sarebbe visibile solo nel file .c; –