Avatar billede Swift Praktikant
13. december 2000 - 22:56 Der er 12 kommentarer og
1 løsning

Problemer med at få oprettet et GLOBAL array !!

I min MAIN.CPP fil ( her ligger main() m.v.) inkluderer jeg MAIN.HPP

I MAIN.HPP definerer & initialiserer jeg et globalt array:
extern int a[ 8 ] = { 0 };

Derefter har jeg 4 andre .CPP filer der alle behandler data fra arrayet.
Jeg får bare fejl lige meget hvad jeg prøver !

FEJL1:
Hvis jeg gør som jeg lige har beskrevet får jeg besked om at:
\"int *  a\" (?a@@3PAHA) already defined in hentsend.obj

FEJL2:
Hvis jeg prøver at flytte defineringen til fx. lige før min main() funktion så får jeg besked om at:
\'a\' : undeclared identifier

HVAD GØR JEG ???
Kan man fx definere arrayet 1 gang som beskrevet - og så \"forklare\" de ekstra filer at de har bare at forstå at arrayet ALLEREDE eksisteret(selvom de ikke kan se det) - og at de iøvrigt ikke skal blande sig i det?
Avatar billede stigc Nybegynder
13. december 2000 - 23:00 #1
overfør en pointer til de funktioner der skal arbejde med dit array!.......
Avatar billede Swift Praktikant
13. december 2000 - 23:06 #2
Hvor skulle du kalde pointeren fra ?
Har du et lille eks. på hvordan det kan gøret ?
Avatar billede stigc Nybegynder
13. december 2000 - 23:48 #3
#include <iostream>
#include \"testklasse.cpp\"
#include \"conio.h\"

int a[]  = {1,2,3,4};
void main() {

testklasse* T = new testklasse();
cout << a[1] << endl;
T->dinfunktion(a);
cout << a[1];
getch();

}




- - - - - - - - - - - - - - - - - - - -

class testklasse {

      public:
      int x;
      testklasse ();
      void dinfunktion(int* ditArray);

};

testklasse::testklasse () {}


void testklasse::dinfunktion(int* ditArray)
      {
          ditArray[1]=999;
      }
Avatar billede stigc Nybegynder
14. december 2000 - 00:50 #4
Dit skulle jo egentlig også virke. Hvis arrayet er defineret før du inkluderer dine 4 cpp.filer
Avatar billede Swift Praktikant
14. december 2000 - 09:01 #5
Ja, men som jeg skriver:
FEJL1:
Hvis jeg gør som jeg lige har beskrevet får jeg besked om at:
\"int *  a\" (?a@@3PAHA) already defined in hentsend.obj

- Det er jo når den er i gang med at linke - så finder den ud af at jeg allerede har defineret arrayet...

Jeg går ud fra at den eneste måde at snakke med sit array er fx:
if( a[5]==1 )
  gør noget...

Og for at gemme en værdi:
a[5] = 1;
Avatar billede Swift Praktikant
14. december 2000 - 09:02 #6
Jeg har ikke umiddelbart mulighed for at ændre i hele koden så der bruges en klasse i stedet for!
Avatar billede moykal Nybegynder
14. december 2000 - 10:30 #7
Jamen det er da også en grundlæggende fejl, at du overhovedet skriver:

extern int a[8] = {}...

extern anvendes (ligesom static) til at erklære linkage typen for en variabel. Hvis du har globale variable - hvilket virkeligt er bad style - sorry - så læg dem evt. på flg. måde:

Global.h:
extern int a[8];
extern double b[42];
:
:
---
Global.cpp:
int a[8] = {0,1,2,3,4,5,6,7};
double b[42] = {0.0,1.0,2.0,...};
---

og de implementations-filer, der har brug for dem kan så inkludere Global.h, så skulle alle problemer være løst. Som sagt er globale variable sjældent god stil, men det kan være nødvendigt. Hvis du vil gøre dig selv en lille tjeneste, og din compiler er nogenlunde up to date, så pak dem i det mindste ind i et namespace:

Global.h:
namespace Global {
  int a[8];
  double b[42];
};
---
Global.cpp:
int Global::a[8] = {....};
double Global::b[42] = {...};

læg mærke til at extern keywordet ikke er nødvendigt. I din implementering skriver du enten:

impl1.cpp:
#include \"Global.h\"
void f(void) {
  int s = Global::a[4]+77;
  :
};

eller

impl2.cpp:
#include \"Global.h\"
using namespace Global;
void f(void) {
  int s = a[4]+77; // namespace Global implicit.
  :

};

i det sidste tilfælde anvendes a automatisk fra namespacet Global.

Det gode ved namespaces er, at du nu roligt kan lade dit program vokse lidt i størrelse uden at være frygtelig bange for name-clashes, dvs. at gode fornuftige variabel-navne kan genbruges, og hvis der er tvivl om at det er variablen x fra namespace Global eller SemiGlobal, jamen så resolver du det da bare med at skrive namespacet foran ligesom i eksempel impl1.cpp.

moykal
Avatar billede soepro Nybegynder
14. december 2000 - 13:00 #8
moykal har ret - problemet er at du sætter initiale værdier på SAMMEN med extern. Det kan compileren ikke finde ud af - eller rettere - compileren ignorer extern, hvis du også indtaster initial-værdier. Hermed får du jo initialiseret din tabel alle steder hvor din .h fil er inkluderet.

(Ærgeligt du nåede at svare først moykal - velkommen på eksperten i øvrigt, du er en flittig svarer ser jeg.)
Avatar billede moykal Nybegynder
14. december 2000 - 13:39 #9
Hej selv, C++ rules, så man kan ligeså godt have det sjovt med det... Er der andre freaks mht. STL, expression-templates etc. derude?
Avatar billede Swift Praktikant
14. december 2000 - 14:16 #10
Jep, jeg har i mellemtiden også selv fundet ud af at det er på denne måde til tilsyneladende hænger sammen.
Men nu har jeg i hvert fald fået det bekræftet.

Altså:
Lige før main() laves en:
int a[8]={0};

Lige før alle andre funktioner(kun en gang pr. fil) der skal bruge arrayet laves en:
extern int a[];
Avatar billede moykal Nybegynder
14. december 2000 - 14:23 #11
Jeg bryder mig altså ikke spor om, at du initialiserer et int-array af længde otte med en værdi. Og som sagt - for Søren - du må for din egen skyld se at gå væk fra globale variable. Der er ubegribeligt mange grunde til at C++ og andre sprog indfører noget der hedder objekt-orienteret bla bla bla men den bedste (synes jeg - fordi Alex Stephanov synes det) er STRUKTUR. Og en del af det at have struktur på sit program er, at lægge den data programmet arbejder på et passende sted. Og vil du ikke lægge skidtet inde i et objekt, så tag \"light-weight\" udgaven (og gå glip af konstrukterer/destruktorer og alle de herligheder de byder på ifm. scope etc.) og det er et namespace. Hvis du ikke kender namespace, så tænk på noget i retning af en struct (helt public klasse) hvor ALT er static, dvs. hverken data eller metoder relaterer til nogen instans, hvorfor konstruktorer/destruktorer også mister deres betydning.

For din egen skyld.

moykal
Avatar billede moykal Nybegynder
14. december 2000 - 14:29 #12
Bjarne Stroustrup - den seneste -  beskriver forøvrigt namespaces perfekt. Hvis du er C++-begynder, er han dog nok ikke lige den bedste at kaste sig over - men afsnittet om namespaces er perfekt. Overvej ellers at læse:

Lippman: http://www.amazon.com/exec/obidos/ASIN/0201824701/o/qid=976800409/sr=2-2/104-4105831-4397502
Meyers:
http://www.amazon.com/exec/obidos/ASIN/0201924889/o/qid=976800453/sr=2-1/104-4105831-4397502
og
http://www.amazon.com/exec/obidos/ASIN/020163371X/o/qid=976800453/sr=2-3/104-4105831-4397502
og engang med tiden:
http://www.amazon.com/exec/obidos/search-handle-form/104-4105831-4397502

specielt Meyers er for fedest...

moykal
Avatar billede moykal Nybegynder
14. december 2000 - 14:30 #13
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester