Modularisierung
-
Hallo,
ich habe das Programm nachvollzogen und es auf meine Bedürfnisse erweitert. Dabei bin ich auf ein Problem/Fehler gestoßen, wenn ich versuche die allocate-Funktion in ein anderes Modula auszulagern.
Hier mein Beispiel:
------------------------------------------------------------------------------
ftypes.htypedef struct { char string[1000]; int number; } Blade; typedef struct { int elements; Blade *pBlade; } Domain;
------------------------------------------------------------------------------
allocate.h
------------------------------------------------------------------------------#include "ftypes.h" Domain* allocate(int n);
------------------------------------------------------------------------------
allocate.c
------------------------------------------------------------------------------#include <stdlib.h> #include "alloc.h" #include "ftypes.h" Domain* allocate(int n) { Domain *newDomain = malloc(sizeof(Domain)); if (newDomain != NULL) { newDomain->pBlade = malloc(sizeof(Blade)*n); if (newDomain->pBlade != NULL) { newDomain->elements = n; } else { printf("Fehler 2!\n"); } } else { printf("Fehler 1\n"); } return newDomain; }
bsp.c
------------------------------------------------------------------------------#include <stdio.h> #include <stdlib.h> #include <string.h> #include "ftypes.h" #include "alloc.h" int main(void) { int ret; int retval; int i, n = 10; Domain *pDomain; pDomain = allocate(n); for (i=0;i<pDomain->elements;i++) { pDomain->pBlade[i].number = i*10; strcpy(pDomain->pBlade[i].string,"Beispieltext"); } for (i=0;i<pDomain->elements;i++) { printf("Element [%d]: '%d'\n", i+1, pDomain->pBlade[i].number); } free(pDomain); return 0; }
Wenn ich versuche das Programm zu übersetzen, erhalte ich folgende Fehler:
gcc alloc.c bsp5.c -o bsp5.exe In file included from alloc.c:3: ftypes.h:4: Fehler: In Konflikt stehende Typen für »Blade« ftypes.h:4: Fehler: Vorherige Deklaration von »Blade« war hier ftypes.h:9: Fehler: In Konflikt stehende Typen für »Domain« ftypes.h:9: Fehler: Vorherige Deklaration von »Domain« war hier alloc.c:5: Fehler: In Konflikt stehende Typen für »allocate« alloc.h:3: Fehler: Vorherige Deklaration von »allocate« war hier alloc.c: In Funktion »allocate«: alloc.c:12: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »printf« alloc.c:15: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »printf« In file included from alloc.h:1, from bsp5.c:6: ftypes.h:4: Fehler: In Konflikt stehende Typen für »Blade« ftypes.h:4: Fehler: Vorherige Deklaration von »Blade« war hier ftypes.h:9: Fehler: In Konflikt stehende Typen für »Domain« ftypes.h:9: Fehler: Vorherige Deklaration von »Domain« war hier
Woran liegt's ?
-
Sieht mir nach fehlenden Includeguards aus.
-
Was beudetet das?
-
-
Die Includeguards verhindern mehrmaliges Einbinden.
Schreib mal deine ftypes.h so:// ftypes.h #ifndef FTYPES_H #define FTYPES_H typedef struct { char string[1000]; int number; } Blade; typedef struct { int elements; Blade *pBlade; } Domain; #endif
-
-
Entschuldigung, blöde Frage, aber ich kriege das immer noch nicht zum laufen.
Also ich versuche genau das hier zu übersetzen...// allocmem.h #include <stdio.h> #include <stdlib.h> #include "inc/allocmem.h" #include "inc/blade.h" #include "inc/sendmsg.h" /* *************************************************************************** */ Domain* allocateDomain(int elements) { Domain *newDomain = malloc(sizeof(structDomain)); if (newDomain != NULL) { newDomain->Blade = malloc(sizeof(structBlade)*elements); if (newDomain->Blade != NULL) { newDomain->Rows = elements; } else { senderrmsg("ALLOCMEM", "Unable to allocate memory for [Domain.Blade]."); } } else { senderrmsg("ALLOCMEM", "Unable to allocate memory for [Domain]."); } return newDomain; }
// blade.h // ************************************************************************** // // STRINGS FOR GLOBALE FILENAMES // ************************************************************************** // #include "globConstants.h" #ifndef BLADE_H #define BLADE_H typedef struct { int i; double x,y,z; double r, rTheta; double betaAngle; } BladeSubDomain; /* *************************************************************************** */ typedef struct { char filename[const_strlen1]; // filename char idirname[const_strlen2]; // input-directory char odirname[const_strlen2]; // output-directory double stagger_angle; // stagger-angle int blades; // number of blades per row BladeSubDomain LE; BladeSubDomain TE; } structBlade; /* *************************************************************************** */ typedef struct { int Rows; // number of blades in Domain structBlade *Blade; } structDomain; #endif
Das sollte doch genau das gleiche sein.
-
Der Fehler lautet:
gcc -c allocmem.c In file included from allocmem.c:4: inc/allocmem.h:3: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »*« token allocmem.c:10: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »*« token
-
Deine allocmem.h musst du noch überdenken:
- Includeguards vergessen.
- Funktionsdefinitionen gehören in eine *.c Datei. In Headerdateien deklariert man üblicherweise die Prototypen der Funktionen.
-
habs gerade selbst gefunden! schön blöder Fehler!!!
structDomain* allocateDomain(int elements) {
-
Noch eine letzte Frage:
Ich würde gerne eine Funktion definieren, die diverse Fehlermeldungen meines Programms auf den Bildschirm ausgibt.
Beispiel
> ERROR@[MODULE]: Der Wert 2 ist größer als 1. Bitte ändern Sie den Wert XYZ in der Steuerdatei ein,
Ich würde die Ausgabe gerne auf zwei Funktionen (1 und 2 Zeile) aufteilen.
1. Die erste Zeile erhält die Info, in welchem Modul der Fehler auftrat sowie den Text. Und hier stellt sich mir die Frage, wie ich der Funktion einen Text, in dem auch Zahlen "2" und "1" auftauchen, als String übergebe?2. Für die zweite Zeile muss der Funktion mitgeteilt werden, wieviele Tabs bzw. Leerzeichen vor dem Text stehen sollen. Wie macht man das geschickt?
Für bessere / professionellere Vorschläge bin ich gerne offen....
-
Ich mache das z.Zt. ungefähr so:
// msg.h //... // Include Guards nicht vergessen :D char* msg_mk (char*, ...); //...
// msg.c #define MSGLEN_MAX 1024 static char msgbuf[MSGLEN_MAX+1] = {0}; #ifdef WIN32 #define vsnprintf _vsnprintf #endif char* msg_mk (char* a, ...) { const int n = MSGLEN_MAX; va_list v; va_start(v,a); vsnprintf(msgbuf, n, a, v); va_end(v); return msgbuf; }
// main.c #include "msg.h" int main (void) { char* e = "You have moved your mouse. Restart Windows for the " "change to take effect."; while (type = check_input()) { switch(type) { case MOUSEMOVE: puts ( msg_mk ("Error nr: %d in file %s line %d occured! " "The message is: %s.\n", 88, __FILE__, __LINE__, e )); exit(1); break; //...
-
Könntest Du bitte einmal kurz erklären, was genau Du mit den Funktionen
va_list v; va_start(v,a); vsnprintf(msgbuf, n, a, v); va_end(v);
bewirkst. Und was ist "vsnprintf _vsnprintf" für eine Funktion?
Ist es in C möglich optionale Parameter für eine Funktion zu definieren?
-
Phil270307 schrieb:
Ist es in C möglich optionale Parameter für eine Funktion zu definieren?
klar. (...) heisst, dass der aufrufer die anzahl der argumente bestimmen kann.
http://en.wikipedia.org/wiki/Variadic_function#Variadic_functions_in_C.2C_Objective-C.2C_C.2B.2B.2C_and_D
-
Die Macros va_list, va_end werden z.B. hier mit Beispielen erklärt:
http://pronix.linuxdelta.de/C/standard_C/c_programmierung_21.shtml
Die Funktion vsnprintf arbeitet mit va_list zusammen, ist ähnlich wie snprintf.Das define vsnprintf -> _vsnprintf brauchst du vielleicht gar nicht, wenn du einen neueren Compiler hast.
-
Hallo,
ich habe noch ein Problem, was ich nicht in den Griff bekomme/verstehe.
Ich versuche vergeblich in ein Element meiner Struktur einen Sinus/Cosinus/Tangens-Ausdruck zu schreiben.
#include <math.h> #define CNTLBLDLE Domain->Blade[bldID].LE CNTLBLDLE.r = sin(3.14152);
Sobald ich eine trigonometrische Funktion auf ein double-Element in der Strutkur anwende, erhalte ich den Fehler "undefined reference to 'sin'".
Woran liegt das? Und wie kann man den Fehler beheben?Noch eins - kann mir jemand sagen, wo ich eine gute Anleitung finde, um mein C-Projekt in Eclipse zu importieren und ein Makefile automatisch zu generieren?