Hallo
Wäre cool wenn mir jemand sagen könnte, was an diesem Code hier nicht
korrekt ist:
1
typedefunion{
2
unsignedshortu16;
3
struct{
4
unsignedcharlowbyte:8;
5
unsignedcharhighbyte:8;
6
}byte;
7
struct{
8
unsignedcharb0:1;
9
unsignedcharb1:1;
10
unsignedcharb2:1;
11
unsignedcharb3:1;
12
unsignedcharb4:1;
13
unsignedcharb5:1;
14
unsignedcharb6:1;
15
unsignedcharb7:1;
16
}bit;
17
}FontType;
18
19
struct{
20
FontTypeHeader;
21
unsignedshort*Data;
22
unsignedcharWidth;
23
unsignedcharHeight;
24
unsignedcharStyle;
25
unsignedcharLetterSpacing;
26
unsignedcharNumberOfChars=Header.byte.highbyte;
27
unsignedcharIsFixed=Header.bit.b0;
28
unsignedcharIsVariable=Header.bit.b1;
29
unsignedcharIsScanX=Header.bit.b6;
30
unsignedcharIsScanY=Header.bit.b7;
31
unsignedcharIsExtendedHeader=Header.bit.b3;
32
}TFont;
Es geht darum, Code von Basic nach C zu übersetzen, wobei der
Basic-Compiler schon Funktionen zum Zugriff auf High-/Lowbyte und
einzelne Bits eingebaut hat. TFont existierte entsprechend schon, so
dass ich mir etwas einfallen lassen muss, um das so ähnlich wie möglich
in C beibehalten zu können.
Jedenfalls wirft der Compiler im TFont-Struct auf den Zeilen, wo ich die
FontType-Variable Header verwende, einen Fehler dieser Art:
../Graphics.c:186: error: expected ':', ',', ';', '}' or '__attribute__'
before '=' token
Vielen Dank.
Grüsse
Martin
P.S.: Eine weitere Frage brennt mir auch schon unter den Nägeln: Wenn
das Problem oben gelöst ist, wie greife ich dann auf die
Pointer-Variable zu? *Font.Data?
Hi
ich hab die obige Definition mal im Borland C++ Builder eingefügt. Der
Borland meckert das hier an:
unsigned char NumberOfChars = Header.byte.highbyte;
unsigned char IsFixed = Header.bit.b0;
unsigned char IsVariable = Header.bit.b1;
unsigned char IsScanX = Header.bit.b6;
unsigned char IsScanY = Header.bit.b7;
unsigned char IsExtendedHeader = Header.bit.b3;
"Zuweisung von Werten während der Definition nicht möglich."
Zugriff würde erfolgen: TFiont.Header.u16 = 0; z.B.
Da es innerhalb vom Borland C++ Builder schon ein "TFont" gibt, ist eine
Variable oder Definition von TFont ungünstig. Müsste also bei Borland
idealerweise anders heissen.
Gruß
Gerhard
Ja genau, AVR-GCC meckert nur bei der ersten der von dir erwähnten
Zeilen, wenn man die auskommentiert bei der nächsten etc...
Was heisst das jetzt genau? Sorry da komm ich nicht selbst drauf, kann
ein Spezi mir bitte den entschedenden Hinweis geben, danke.
Gruss
Martin
Martin Geissmann schrieb:
> Was heisst das jetzt genau?
Was heisst was?
Beziehst Du Dich auf
> "Zuweisung von Werten während der Definition nicht möglich."
Was verstehst Du daran nicht?
>Was heisst das jetzt genau? Sorry da komm ich nicht selbst drauf, kann>ein Spezi mir bitte den entschedenden Hinweis geben, danke.
Datt jeht in C und auch in C++, und eigentlich auch sonst grundsätzlich,
so nicht. Du versuchst, einer Variablen einen Wert aus einer anderen
Variablen zuzuweisen, obwohl diese andere noch gar nicht initialisiert
ist.
Das wird so auch in Basic nicht gehen, da wirst du ein paar Zeilen
Programmcode basteln müssen.
Der C-Compiler meckert allerdings aus einem anderen Grund:
Variablen lassen sich in C während der Deklaration nur mit Konstanten
initialisieren, und Konstanten meint da wirklich Konstanten im Sinne von
42.
C++ würde auch constant deklarierte Variablen akzeptieren, aber nichtmal
so etwas hast du vorliegen.
Oliver
Ausserdem ist die ganze Vorgehensweise, sofern ich die Absicht dahinter
richtig interpretiere, mehr als zweifelhaft (auch wenn das gültiges C
wäre).
Man speichert nicht dieselbe Information 2 mal in einer Datenstruktur!
Niemals.
Erstens ist es Platzverschwendung
Zweitens hat man immer das Problem, dass die beiden Informationsträger
auseinanderlaufen können und dann stellt sich die Frage: Welche gilt
denn jetzt?
Schmeiss die Member NumberOfChars, IsFixed, IsVariable, IsScanX, IsScanY
und IsExtendedHeader aus der struct raus und ersetze sie durch
Zugriffsfunktionen, die sich die relevanten Werte direkt aus Header
holen bzw. dort ablegen.
Heinz Heizer schrieb:
> Das ist doch ein Union, da greift er doch auf den gleichen> Speicherbereich zu, oder nicht?
Nö.
Die Idee, so wie ich das aus dem Code rauslese, ist es einen Member
Header zu haben, in dem alles drinnen ist.
struct {
FontType Header;
Und irgendwie magisch sollen sich die Member
unsigned char NumberOfChars = Header.byte.highbyte;
unsigned char IsFixed = Header.bit.b0;
unsigned char IsVariable = Header.bit.b1;
unsigned char IsScanX = Header.bit.b6;
unsigned char IsScanY = Header.bit.b7;
unsigned char IsExtendedHeader = Header.bit.b3;
magisch an diesem Header bedienen und einzelne Informationen daraus in
neuen Members magisch zur Verfügung stellen.
Das hat erst mal nichts mit der Union an sich zu tun
struct {
int i;
int j = i;
}
wäre eine kürzere Version mit genau der gleichen Grundidee.
Das das so in C nichts wird, dürfte klar sein. Da wird wohl in BASCOM
ein Alias gestanden haben. Den muss man aber in C anders implementieren.
Ja, aber warum macht ersich erst eine union, nur um sie dann gleich
wieder in einer structure zu verwenden? Das ist das doppelte was Kar
heinz meint.
Ausserdem, wenn man schon eine Struktur will und sie gleich
initialisieren will dann bitte so:
>Ja, aber warum macht ersich erst eine union, nur um sie dann gleich>wieder in einer structure zu verwenden? Das ist das doppelte was Kar>heinz meint.
Weil das mit dem union noch nicht richtig angekommen ist.
Ein Auszug aus dem Original Basic-Source wäre angenehm. Letztlich läuft
es auf sowas hinaus:
struct {
unsigned char Width;
unsigned char Height;
unsigned char Style;
unsigned char LetterSpacing;
unsigned char NumberOfChars;
// Alles in einem Byte
unsigned char IsScanY : 1;
unsigned char IsScanX : 1;
unsigned char Unused : 3;
unsigned char IsExtendedHeader : 1;
unsigned char IsVariable : 1;
unsigned char IsFixed : 1;
} THeader;
struct {
struct THeader Header;
unsigned short *Data;
} TFont;
Ich poste euch hier wie gewünscht mal noch den original Basic-Code
(nicht Bascom):
1
Public Structure TFont
2
Header As Word
3
Data As Word
4
Width As Byte
5
Height As Byte
6
Style As Byte
7
LetterSpacing As Byte
8
NumberOfChars As Header.Byte1
9
IsFixed As Header.Booleans(0)
10
IsVariable As Header.Booleans(1)
11
IsScanX As Header.Booleans(6)
12
IsScanY As Header.Booleans(7)
13
IsExtendedHeader As Header.Booleans(3)
14
End Structure
Die Byte1 und Booleans-Makros stehen hier offenbar schon zur Verfügung.
Wie gesagt, es ging mir darum, dass ich in C genau gleich auf die Daten
zugreifen kann wie im Originalprogramm, egal ob es schönes C ist oder
nicht. Wahrscheinlich kommen da aber noch viele weitere Probleme hinzu,
so dass wohl nichts daraus wird.
Gruss
Martin
Nun ja, du wirst zunächst mal verstehen müssen, was der Basic-Code da
wirklich bedeutet. Dann lässt sich sowas auch in C nachbauen.
Meine Vermutung ist die, daß da tatsächlich eine Art union entsteht, die
das header-byte zusätzlich in einzelne bits auflöst. Etwa in der Art: