Toon posts:

[c++] Array of structures

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,


Ik heb de volgende structure:

code:
1
2
3
4
5
6
7
8
9
  typedef struct

  {
     String Name;
     int Number;

  } SItem;
 
  SItem ItemStruct[100];


Hiervan wil ik ItemStruct[5].Number t/m ItemStruct[15].Number in een nieuwe array van integers hebben. Dit kan door een kopie te maken:

code:
1
2
3
4
5
6
int arr[100];

for(int i=0;i<10;i++)
{
   arr[i]=ItemStruct[i+5];
}


Maar dit is alleen maar processortijd verspilling. Kan dit ook op een andere manier?
Zoals bijvoorbeeld:

code:
1
2
3
int arr1[20]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
 int *parr2;
 parr2=&arr1[5];

(nu is parr2[0] gelijk aan arr[5] en parr2[1] is gelijk aan arr[6] etc.)

Kortom, is de bovenstaande methode ook mogelijk met een array van structures, ipv een array van integers?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Nee, uiteraard niet. Een int is 4 bytes (meestal op 32-bits systemen dan). sizeof (int) == 4. Jouw structure is meer dan 4 bytes, er zit namelijk ook nog een string in.

Een array van SItem's ziet er in het geheugen zo uit (stel even dat string ook 4 bytes is):
String | int | string | int | string | int

Als je dat gaat mappen op ints, dan krijg je dus
int | int | int | int | int | int

de indices 0, 2 en 4 slaan dus helemaal nergens op, omdat dat strings zijn, en geen ints

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Eerlijkgezegd vind ik je de opzet processortijd/geheugenverspilling, waarom maak je uberhaupt een extra array aan als alles wat je wilt hebben ook in de bestaande array staat, zelfs eenvoudig te benaderen...

Als je die array maakt omdat die doorgegeven moet worden aan een functie o.i.d. dan is het wel weer logisch dat je dit doet en ook zeker geen processortijd- en geheugenverspilling, maar noodzaak.

Verwijderd

Topicstarter
Maar als ik nu ga steppen met de grootte van de Struct en deze vervolgens deze omvorm naar een integer? Dit zou bijvoorbeeld met assembler wel kunnen. Kan dit ook in C++?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

dat is dan toch gewoon hetzelfde als de array gewoon benaderen als array van SItem's? Da's nog leesbaarder ook

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Ja en nee, de array is namelijk een invoer van een functie. Deze functie komt van een COM/DCOM server als interface en kan ik dus niet aanpassen. Zou ik geen array aan kunnen maken met hierin de adressen die naar het desbetreffende item uit de structure wijzen?

Verwijderd

Verwijderd schreef op 01 mei 2003 @ 11:51:
Maar als ik nu ga steppen met de grootte van de Struct en deze vervolgens deze omvorm naar een integer? Dit zou bijvoorbeeld met assembler wel kunnen. Kan dit ook in C++?
Dat is precies wat in je symboliseert door "ItemStruct[i].Number" Dat is namelijk hetzelfde als
*(&(ItemStruct[0].Number) + (i * sizeof(SItem)))
Mag jij zeggen wat leesbaarder is... En of je nu vanuit C/C++ of assembly deze data benadert maakt echt niks uit, in alle gevallen komt het op precies dezelfde adresgeneratie neer..

offtopic:
"assembly" is overigens de naam van de taal, een "assembler" is de applicatie die assembly vertaalt naar een objectformaat, net zoals "C" en "C++" talen zijn en een compiler een applicatie.

[ Voor 5% gewijzigd door Verwijderd op 01-05-2003 12:45 ]


Verwijderd

Verwijderd schreef op 01 May 2003 @ 12:09:
Ja en nee, de array is namelijk een invoer van een functie. Deze functie komt van een COM/DCOM server als interface en kan ik dus niet aanpassen. Zou ik geen array aan kunnen maken met hierin de adressen die naar het desbetreffende item uit de structure wijzen?
Dat kan dus alleen als de functie dat als alternatief voor de invoer toestaat (ik neem aan dat die functie ook al voorgedefineerd is, anders kun je een functie maken die "const SItem&" als argument accepteert.)
Anders zul je toch echt je data moeten "processen", als we dat altijd konden voorkomen, waren er een stuk minder programmeurs en programma's...

[ Voor 3% gewijzigd door Verwijderd op 01-05-2003 12:37 ]


Verwijderd

Topicstarter
Als ik het goed begrijp kan dan zou je als invoer voor de functie ItemStruct[5].Number kunnen nemen? In principe zal dan dus het volgende ook moeten werken:

code:
1
2
3
int *parr;

parr=&ItemStruct[5].Number;


Hierna zal parr[0] gelijk moeten zijn aan ItemStruct[5].Number en parr[1] gelijk moeten zijn aan ItemStruct[6].Number?
Dit heb ik getest, parr[0] heeft wel de goede waarde, parr[1] niet.
Heb ik dit goed geinterpreteerd?

Verwijderd

Verwijderd schreef op 01 mei 2003 @ 12:57:
Als ik het goed begrijp kan dan zou je als invoer voor de functie ItemStruct[5].Number kunnen nemen? In principe zal dan dus het volgende ook moeten werken:
C++:
1
2
3
int *parr;

parr=&ItemStruct[5].Number;

Hierna zal parr[0] gelijk moeten zijn aan ItemStruct[5].Number en parr[1] gelijk moeten zijn aan ItemStruct[6].Number?
Dit heb ik getest, parr[0] heeft wel de goede waarde, parr[1] niet.
Heb ik dit goed geinterpreteerd?
Nee, nee, nee. sizeof(SItem) is nooit gelijk aan sizeof(int), en wat jij doet met parr[i] met parr als pointer naar int komt neer op: *(&(ItemStruct[0].Number) + (i * sizeof(int)))

Zie eerdere post dat dat dus de totaal verkeerde offset is voor StructItem[1].Number !!!

Maar dit zou wel kunnen:
C++:
1
2
3
4
5
SItem *parr = &ItemStruct[5];
int aValue = *parr->Number;
int otherValue = parr[1].Number;
*parr++;
int anotherValue = *parr->Number;

Als jouw functie als argument een integer-array nodig heeft, zul je toch echt een nieuwe array moeten maken en daar al je Number members naartoe moeten kopieren...

[ Voor 5% gewijzigd door Verwijderd op 02-05-2003 09:12 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het mooist is natuurlijk het gebruik van iterators, dan is de onderliggende representatie helemaal niet belangrijk. Maar ja, dan moet je wel de implementatie van die functie die een int array accepteert aanpassen ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • PiepPiep
  • Registratie: Maart 2002
  • Laatst online: 08-06 11:02
[quote]Verwijderd schreef op 01 mei 2003 @ 11:29:
code:
1
2
3
4
5
6
7
8
9
  typedef struct

  {
     String Name;
     int Number;

  } SItem;
 
  SItem ItemStruct[100];

code:
1
int arr[100];

Als je SItem wel kan aanpassen :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  typedef struct

  {
     String Name;
     int *Number;

  } SItem;
 
  SItem ItemStruct[100];
  int arr[100];
  for (int teller=0; teller<100; teller++)
  {
    ItemStruct[teller].Number=&arr[teller];
  }

Dan staan alle int's wel netjes op een rijtje en dus kan je ze meegeven.

[edit]
Wel opletten dat SItem.Number dus geen int meer is maar nu een int *

[ Voor 8% gewijzigd door PiepPiep op 01-05-2003 19:16 ]

486DX2-50 16MB ECC RAM 4x 500MB Drive array 1.44MB FDD MS-Dos 6.22


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
PiepPiep's methode is redelijk, maar om het netjes te doen moet je meer doen:

Number een method maken
De array SItem[100] tot een (enkele) class SItemContainer te maken
De hulparray int arr[100] tot een member van die class te maken.
De DCOM methode alleen aanroepen vanuit de SItemContainer methods.

En waarschijnlijk wil je std::vector<SItem> gaan gebruiken.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1