Seite 1 von 2

Anzahl der Felder in einer Structure ermitteln

Verfasst: 02.07.2020 22:21
von Olafmagne
Hallo,
Meine Frage ist,wie man die Anzahl der Felder einer Structure ermitteln kann.
Grund ist die Idee einer 'Universelle' Procedure,die sich die Anzahl selber ermittelt,
um nicht immer alles für jede Stucture neu zu schreiben.
SizeO f()gibt die Grösse in Byte,
was mir aber nicht hilft.
Wäre nett,wenn jemand 'ne Idee hätte
Gruss
Olaf

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 02.07.2020 23:26
von darius676
Verstehe die Frage??? nicht???

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 02.07.2020 23:31
von RSBasic
Mir ist nur die Variante mit InsertXMLStructure() bekannt, um dort die Anzahl zu ermitteln:

Code: Alles auswählen

EnableExplicit

Structure MyStructure
  Hello.i
  Pure.i
  Basic.i
EndStructure

Define MyStructure.MyStructure
Define *node

If CreateXML(0)
  InsertXMLStructure(RootXMLNode(0), MyStructure, MyStructure)
  *node = MainXMLNode(0)
  Debug XMLChildCount(*node)
EndIf
Meinst du sowas?

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 03.07.2020 01:19
von Olafmagne
@RSBasic
Nein, es geht darum zB
3 oder 4 Structuren mit unterschiedlicher anzahl an Felder (für LinkedList)
zur Laufzeit soll mit einer Procedure alle Listen bearbeitet werden,ohne dass ich jetzt schon weiss,welche gerade bearbeitet wird
Die anzahl der Elemente pro List ist kein Problem,kann mit 'Bordmittel' erfragt werden,ABER,
wie ermittele ich,wieviele Felder die gerade bearbeitete Structure hat?

Einzige gefundene Lösung ist,jede Structure mit' Align' zu erstellen,um dann über die 'SizeOff' Funktion/Align die anzahl der Felder zu berechnen.
dann aber Würde ich,um die Procedure Universal auch für andere prg's zu nutzen Speicherplatz verschenken.
Bei überschaubaren Codelänge wohl noch akzeptable.
mich interessiert nun,ob es auch eine andere Lösung dafür gibt
Der Nutzen wäre zB, eine List zu durchsuchen,um Doubletten zu finden und zu löschen.
Dazu muss ich jedes Feld vergleichen,doch,wieviele?
Wie gesagt,ich werde es ermal mit 'Align' machen(erster test functioniert),
eine bessere Möglichkeit ist aber auf jeden Fall Willkommen

Olaf

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 03.07.2020 07:02
von ST4242
Hallo

ich bin nicht sicher ob Du die unterschiede zwischen Befehlen und Compilerbefehlen kennst.

Der Befehl SizeOf(Structrure) ist ein Compilerbefehl. Das heisst, beim compilieren des Porgramms wird der Wert ermittelt und ändert sich zur Laufzeit nicht.

Wenn du in einer Prozedur unterschiedliche Structuren verarbeiten möchtest, brauchst Du meines Wissens schon etwas handarbeit.

z.B. So

Structure klein
Wert1.i
Wert2.i
endstructure

Structure Gross
Wert1.i
Wert2.i
Wert3.i
Endstructure


procedure Bearbeite(*daten.gross,AnzahlWerte.i)
select AnzahlWerte
case
.....

endselect
endprocedure

define daten1.klein,daten2.gross

Bearbeite(@daten1,2) ; Du mußt beim Aufruf wissen welche Strukur due übergibst
Bearbeite(@daten2,3)
;--

Allerdings müssen die Strukturen entsprechend ähnlich sein.

Ich hoffe Dich nicht verwirrt zu haben.

Gruß Stefan

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 03.07.2020 09:52
von NicTheQuick
Nur weil du weißt wie viele Felder eine Struktur hast, weißt du doch noch lange nicht wie diese Felder heißen um sie anzusprechen. Was bringt dir das also?
Ich weiß noch, dass es viele Windows-API-Befehle gibt/gab, bei denen man die Strukturgröße in das allererste Feld der Struktur geschrieben hat, damit die Funktion, der man einen solchen strukturierten Wert übergab, wusste wie viel in der Struktur drin stand. Das war hauptsächlich um zwischen Versionsunterschiedenen zu unterscheiden. In neuen Windows-Versionen hatte die Struktur mehr Felder als in älteren, hatte aber den selben Namen.

Deine Align-Idee ist aber eh nicht schlecht. Es empfiehlt sich sowieso nicht mit Ascii, Byte, Word, Unicode, Character oder Long zu arbeiten, sondern immer mit Integer, weil das das natürliche Alignment des Speichers ist, sowohl im RAM als auch im Cache. Nicht korrekte ausgerichtete Werte können im schlimmsten Fall den Zugriff auf zwei benachbarte Speicherfelder zur Folge haben, wodurch der Zugriff auf sie langsamer ist. Außerdem muss die CPU selbst noch Bitshift-Logik anwenden um die Werte erst mal verarbeitbar zu machen. Und wenn alles aligned ist, dann kannst du ja wieder mit sizeof arbeiten.
Bleibt die Frage, ob du Felder aus statischen Arrays als ein Feld zählst oder ob das mehrere für dich sind. Und was du überhaupt mit Strings machst.

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 03.07.2020 12:07
von Olafmagne
@ST4242
DerUnterschied ist mir bekannt,und da sich die Structure nicht ändert,
ist die bestimmung zur compilezeit in ordnung

@NicTheQuick
Hab mir gestern Nacht so beim einduseln die Frage gestellt,
WAS ich denn da einlesen soll!!
Einschlafen war nicht mehr

Nach ein paar Tassen Kaffée war mir dann klar,dass es wohl nur mit align gehen würde
Also align auf grössten Type zB *Pointer,bei X64 =8 Byte
Sizeof() =Grösse der Struct zB 32 Byte
so dass 32Byte/8Byte=4Felder
Der Datentype ist egal,da nur auf gleichheit geprüft wird,kann dass Bitweise geschehen

Code beispiel

Code: Alles auswählen

Structure MyTest Align 8
  text$
  ;Daita.i
  Datai.f
  ;Quark.l
  Etwas.i
  nix.a
  ;waisniks.b
  stuss.d
  stussiger.f
EndStructure

;Felder ein/auskommentieren um Structuregrösse zu ändern

Debug "SizeOf(MyTest)="+SizeOf(MyTest)
c=SizeOf(MyTest)/8
Debug "StructureGrösse/Align;(hier align=8) ergibt "+c


Olaf

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 03.07.2020 12:35
von STARGÅTE
Wenn man an eine Prozedur einen Parameter mit verschiedenen Strukturen übergeben möchte, wird (wie ich das mitbekommen habe) üblicherweise im ersten Strukturfeld der Typ der Struktur übergeben:
API without Secrets: Introduction to Vulkan* Part 1: The Beginning

Auch ich selbst verwende diese Methode, wenn ich universelle Prozeduren schreiben möchte die viele verschiedene Strukturen verwenden soll, zum Beispiel so:

Code: Alles auswählen

Structure Head
	Type.i
EndStructure

Enumeration 1
	#TYPE_INTEGERS
	#TYPE_FLOATS
EndEnumeration

Structure Integers Extends Head
	List Integers.i()
EndStructure

Structure Floats Extends Head
	List Floats.f()
EndStructure

Procedure.i Count(*Values.Head)
	Protected *Integers.Integers = *Values
	Protected *Floats.Floats     = *Values
	Select *Values\Type
		Case #TYPE_INTEGERS
			ProcedureReturn ListSize(*Integers\Integers())
		Case #TYPE_FLOATS
			ProcedureReturn ListSize(*Floats\Floats())
		Default
			ProcedureReturn -1
	EndSelect
EndProcedure

Define Integers.Integers\Type = #TYPE_INTEGERS
AddElement(Integers\Integers()) : Integers\Integers() = 1

Define Floats.Floats\Type = #TYPE_FLOATS
AddElement(Floats\Floats()) : Floats\Floats() = 0.5
AddElement(Floats\Floats()) : Floats\Floats() = 0.2

Debug Count(Integers)
Debug Count(Floats)

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 03.07.2020 13:30
von Olafmagne
@Stargate

Da ich nur die Gleichheit der Felder einer Structurierten Liste prüfen will,
die Procedure ein Include werden soll und
es eigentlich egal ist,welchen Type das Feld hat,(BitMuster reicht ja schon)
und ich die Anzahl der Felder nur brauche,um die Leseroutine pro ListElement zu Initalisieren,
ist der Type erst mal egal.
Allerdings muss ich entweder den Type zum lesen des Feldes haben,oder einfach nur schauen,was da steht.
der Wert ist nicht wichtig(ob .a,.b,.c,.d,.f,.s,...),es wird ja nur Listindex1\1. Feld mit Listindex2\1. Feld verglichen,
(man kann auch sagen vergleiche 2 Wörter,ohne die Sprache zu kennen,durch vergleich Buchstabe-für-Buchstabe).

Da die Frage,Anzahl der Felder, gelöst ist,
übergabe einer Liste an Procedure kein Problem,
auslesen eines Speicherbereiches ebenfalls bekannt,
Muss nur die Structure mit Align erstellt werden UND das erste Feld denAlignwert erhalten ODER alle Structs haben den gleichen wert.

Olaf

Edit:Die Felder müssen nicht als StructureFeld gesehen werden,sondern einfach als ein Stück Speicher

Re: Anzahl der Felder in einer Structure ermitteln

Verfasst: 03.07.2020 14:27
von NicTheQuick
Ich hätte das ja dann irgendwie so gemacht:

Code: Alles auswählen

Structure Various
	StructureUnion
		a.a
		b.b
		c.c
		d.d
		f.f
		i.i
		l.l
		q.q
		u.u
		w.w
	EndStructureUnion
EndStructure

Structure VariousList
	f.Various[0]
EndStructure

Structure VariousListInclude
	_size.i
	_any.VariousList
EndStructure

Macro StructureList(name)
	Structure name Extends VariousListInclude Align SizeOf(Various)
EndMacro

StructureList(MyStruc1)
	feld1.a
	feld2.d
EndStructure

StructureList(MyStruc2)
	E.i
	scha.f
	kar.l
EndStructure

Procedure showStruc(*var.VariousListInclude)
	If *var\_size = SizeOf(MyStruc1)
		Debug *var\_any\f[0]\a
		Debug *var\_any\f[1]\d
		
	ElseIf *var\_size = SizeOf(MyStruc2)
		Debug *var\_any\f[0]\i
		Debug *var\_any\f[1]\f
		Debug *var\_any\f[2]\l
	EndIf
EndProcedure


Define a1.MyStruc1
a1\_size = SizeOf(MyStruc1)
a1\feld1 = 1
a1\feld2 = 2.3

Define a2.MyStruc2
a2\_size = SizeOf(MyStruc2)
a2\E = 4
a2\scha = 5.6
a2\kar = 7

showStruc(a1)
showStruc(a2)
In showStruc wird dann anhand der Strukturengröße unterschieden welche Struktur ausgelesen wird. Die Felder werden per Index (z.B. f[1]) angesprochen und je nach Typ (z.B. f[1]\d) interpretiert.