Ich habe ein Array in einer Datei definiert und in einer anderen muss ich es verwenden, z.
/* a.c - defines an array */
int a[] = {1,2,3,4,5,6,7,8,9};
/* b.c - declare and use it. */
#define COUNT ((sizeof a)/(sizeof int))
extern int a[]; //size of array
.
.
.
int i;
for(i=0; i<COUNT; i++)
printf("%d", a[i]);
.
.
.
Wenn ich jetzt versuche, es zu kompilieren, wurde mir der Fehler angezeigt, dass sizeof nicht für unvollständige Typen verwendet werden kann.
Kann mir jemand sagen, wie man mit einem solchen Fall in C/C++ umgeht? Ich möchte nicht in ac tiefgestellt werden
Danke im Voraus
Ich bin heute auf dieses Problem gestoßen. Ich dachte, wenn der Linker die Referenzen externer Objekte auflösen kann, dann kann er auch ihre Größen auflösen … Aber es scheint, dass die Linker noch nicht so schlau sind …
– Kalmarius
18. Dezember 2013 um 19:40 Uhr
Beim Kompilieren von bc kennt der Compiler die Größe von nicht a – Sie haben es nicht gesagt. Alles, was es weiß, dass ein int-Array aufgerufen wird a existiert in einem anderen Modul. Der Verknüpfungsprozess löst Objektadressen, aber keine Größen auf.
– Seva Alexejew
15. Dezember 2018 um 15:02 Uhr
Markus Wilkins
Sie könnten so etwas wie das Folgende einfügen a.c und extern dann aus b.c.
Im Wechselstrom:
int a[] = {1, 2, 3};
const int lengthofa = sizeof( a ) / sizeof( a[0] );
Und dann in bc:
extern int a[];
// the extern (thanks Tim Post) declaration means the actual storage is in another
// module and fixed up at link time. The const (thanks Jens Gustedt) prevents it
// from being modified at runtime (and thus rendering it incorrect).
extern const int lengthofa;
void somefunc() {
int i;
for ( i = 0; i < lengthofa; i++ )
printf( "%d\n", a[i] );
}
Es ist eigentlich falsch, dass die const würde Laufzeitänderungen verhindern. Abgesehen von der beabsichtigten Modifikation durch Umformungen ((int)lengthofa = <something>), haben auch Pufferüberläufe eine gute Chance, den Wert zu verändern. Ich sehe keinen Grund, die Array-Größe in diesem Fall nicht explizit anzugeben (vorzugsweise durch Verwendung eines ‘#define MAGICNUM ‘. Oder so etwas wie #define LENGTHOFA(a) sizeof (a) / sizeof ((a)[0]) stattdessen.
– polynomial_donut
16. Oktober 2018 um 17:44 Uhr
WENN Sie MISRA – C einhalten müssen, tun Sie dies nicht extern int a[]MISRA – C:2004, 8.12 “Wenn ein Array mit externer Verknüpfung deklariert wird, wird seine Größe muss explizit angegeben oder implizit durch Initialisierung definiert werden.”
– Undefiniertes Verhalten
14. Januar 2019 um 13:28 Uhr
Wenn Sie möchten, dass Ihre Arraygröße als Konstante zur Kompilierzeit zugänglich ist, haben Sie keine andere Wahl, als die Arraygröße explizit in der anzugeben extern Deklaration des Arrays
extern int a[9];
In diesem Fall liegt es in Ihrer Verantwortung, sicherzustellen, dass die Array-Größe zwischen den konsistent ist extern Deklaration und Definition. Sie können dafür eine Manifest-Konstante verwenden, aber es liegt dennoch in Ihrer Verantwortung, sicherzustellen, dass die Anzahl der Initialisierer zwischen den {} und die angegebene Größe sind gleich.
Wenn Sie die Arraygröße nicht als Konstante zur Kompilierzeit haben möchten, können Sie tun, was Mark Wilkins in seiner Antwort vorschlägt.
Wenn Sie diesen Pfad verwenden und Visual Studio verwenden, wird die Anzahl der Elemente in einer QuickInfo angezeigt, wenn Sie den Mauszeiger über die Deklaration bewegen.
– Tschumann
23. Dezember 2018 um 5:38 Uhr
Der Compiler verfügt beim Kompilieren von bc nicht über genügend Informationen, um die Größe des Arrays zu bestimmen. Diese Informationen befinden sich nur in ac, wo sich Ihre Initialisiererliste im Geltungsbereich befindet.
Sie müssen die Größe irgendwie mitteilen. Eine Methode besteht darin, eine int-Konstante mit der Größe zu definieren und diese ebenfalls extern. Eine andere Möglichkeit wäre die Verwendung eines Sentinels (ein Wert außerhalb Ihres gültigen Datenbereichs), um das Ende des Arrays anzuzeigen.
Ich würde #define ARRAY_MAX (or whatever) in einem externen Header, der im Allgemeinen zum Definieren solcher Dinge verwendet wird, dann fügen Sie diesen Header in beide Dateien ein, die ihn benötigen. Dies funktioniert gut, wenn Sie dazu neigen, die meisten, wenn nicht alle von Ihnen zu behalten defines in einem oder zwei zentralen Headern.
Meiner Meinung nach wird es nicht kompiliert, wenn Sie keine Definition haben und mit sizeof a in einer Datei definieren.
Dateien werden als *.obj / *.a Dateien kompiliert und gespeichert. Sie können Arrays aus anderen Dateien dank der Extern-Deklaration verwenden, die nach dem Kompilieren beim Linken überprüft wird.
Sie wollen define deklarieren (hier muss der Präprozessor helfen. Er wird vor dem Compilator ausgeführt).
Vor der Kompilierung erhalten Sie also kein Array aus einer anderen Datei …
Haari
Fügen Sie die Variable nur so in die Header-Datei ein:
#ifndef A_DEF
#define A_DEF
int a[] = {1,2,3,4,5,6,7,8,9};
#endif
Die bedingte Kompilierung erlaubt keine Neudefinition von Variablen. Somit haben Sie von überall Zugriff darauf.
13643200cookie-checkExterne Deletion für ein Array?yes
Ich bin heute auf dieses Problem gestoßen. Ich dachte, wenn der Linker die Referenzen externer Objekte auflösen kann, dann kann er auch ihre Größen auflösen … Aber es scheint, dass die Linker noch nicht so schlau sind …
– Kalmarius
18. Dezember 2013 um 19:40 Uhr
Beim Kompilieren von bc kennt der Compiler die Größe von nicht
a
– Sie haben es nicht gesagt. Alles, was es weiß, dass ein int-Array aufgerufen wirda
existiert in einem anderen Modul. Der Verknüpfungsprozess löst Objektadressen, aber keine Größen auf.– Seva Alexejew
15. Dezember 2018 um 15:02 Uhr