Avatar billede driis Nybegynder
25. marts 2003 - 12:42 Der er 11 kommentarer og
1 løsning

At initialisere en struct

Jeg har en structure, hvor jeg ønsker, at alle medlemmer initialiseres til 0, når den oprettes. Hvordan gøres det ?
Avatar billede jpk Nybegynder
25. marts 2003 - 12:46 #1
struct myStruct
{
  int a;
  int b;
  int c;
};

myStruct s = {0,0,0};
Avatar billede jpk Nybegynder
25. marts 2003 - 12:47 #2
eller

myStruct s;
ZeroMemory(&s, sizeof(myStruct));
Avatar billede segmose Nybegynder
25. marts 2003 - 13:03 #3
// Som C 
#include "stdlib.h" // EXIT_SUCCESS
#include "stdio.h" // printf
#include "mem.h"  // memset

struct myStruct {
  int a;
  int b;
  int c;
  myStruct();
};

myStruct::myStruct() {
  memset(this, 0, sizeof(struct myStruct));
}

int main() {
  myStruct my;

  printf("\nmy oh my: %d %d %d\n", my.a, my.b, my.c);

  return EXIT_SUCCESS;
}
Avatar billede olennert Nybegynder
25. marts 2003 - 15:54 #4
Alternativt holde fast i constructor-ideen, og så bruge initializer-list:

myStruct::myStruct()
    : a(0), b(0), c(0)
{ }

Ulempen ved ZeroMemory/memset opstår hvis du smider en mere kompleks type ind i struct'en, som eksempelvis std::string. At lave memset på en std::string er en rigtig dårlig ide under de oversættere jeg har arbejdet med (g++ på Solaris og Linux, aCC på HP-UX, Sun Workshop på Solaris).
Avatar billede driis Nybegynder
25. marts 2003 - 16:06 #5
olenert >> Det var faktisk den metode, jeg var ude efter, men da jpk's første kommentar fungerede fint til mit specifikke formål, brugte jeg det. Et sidespørgsmål: Hvis man bruger initializer-list, kan man så initialisere structure'n til noget andet, når man opretter den ? Altså, f.eks. :

myStruct::myStruct()
    : a(0), b(0), c(0)
{
  int a ;
  int b ;
  int c ;
}

myStruct s1 ; // s1 indeholder nu a = b = c = 0
myStruct s2 = {1,1,1} ; // s2 indeholder a = b = c = 1
Avatar billede jpk Nybegynder
25. marts 2003 - 16:11 #6
Ja, det er jo fint med en konstructor hvis man selv har kodet struct'en, men hvis det er én der ér defineret, går den jo ikke rigtig...
Avatar billede segmose Nybegynder
25. marts 2003 - 17:10 #7
driis - det kan man godt, men man skal så bruge parameter til constructoren og det vil så se sådan ud.

myStruct s2(1,1,1);

med en tilsvarende constructer eller ved brug af copy constructor

myStruct S2 = myStruct(1,1,1);

det er dog mere ineffectivet end første exemple.
Avatar billede segmose Nybegynder
25. marts 2003 - 17:23 #8
olennert - initializer lister er gode.

Hvis der er mange data i structen kan det forekomme at compileren laver noget dårligt arbejde og så er memset meget bedre, her skal man nok over 100 byte før der er forskel.

Hvis der kun laves nogle få instancer af struct'en så brug initializer list, hvis du laver en million i et array og den kun består af simple int/typer, lad være med at bruge nogen af dem, lav istedet en memset på hele array'et.
Avatar billede olennert Nybegynder
26. marts 2003 - 11:36 #9
segmose> Jeg vil nu snarere sige at memset er OK hvis man kun har POD i sin struct. Lige så snart du kommer over i noget mere komplekst (som std::string), så duer memset ikke mere.

Selv hvis du har en struct med en milliard members (lidt overdrevet, forhåbentlig :-) ), så er memset ikke god hvis nogle members er andet end POD.

memset er selvfølgelig mere effektiv end initializer list, men hvis du får sjove core dumps ud af det (noget jeg har været ude for), så hjælper effektiviteten ikke ret meget. Jo, jeg får mit core dump lidt hurtigere end ellers :-).

driis> Ja, du kan sagtens sige myStruct s2 = {1, 1, 1}, det garanterer ANSI C++ standarden.
Avatar billede segmose Nybegynder
26. marts 2003 - 15:12 #10
Det var det jeg forsøgte at sige, kun simple datatyper.

myStruct s2 = {1, 1, 1};

dur i C, men ikke i C++.

Profeten Bjarne siger: When a constructor is explicitly declared fora t type it is not possible to use an initializer list as the initializer (§5.7, 4.9.5).
Avatar billede olennert Nybegynder
26. marts 2003 - 16:01 #11
segmose> Jeg må da være stæreblind, det kan jeg ikke se (C++ Programming Language, Third Edition).

Men jeg kan godt se at du må have ret, for når jeg prøver det fortæller oversætteren mig at jeg er dum (det er ikke helt det fejlmeddelelsen siger, men....).

Så jeg må hjem og læse lidt mere grundigt på 5.7 og 4.9.5.

driis> Undskyld, som segmose skriver har jeg taget fejl. Løsningen må være (igen som segmose foreslår) at lave en c'tor med parametre:

myStruct::myStruct(const int a_, const int b_, const int c_)
  : a(a_), b(b_), c(c_)
{ }

myStruct s1(1, 1, 1);
Avatar billede segmose Nybegynder
26. marts 2003 - 16:26 #12
Det er i kapitel 11.3.3 sidste paragraf. De andre er vist henvisninger til standarden.
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