Hallo!
Ich habe folgendes Problem....
Ich programmiere in C für einen PIC 18F4550. Ich habe mehrere *.c Files
in meinem Projekt und alle benutzen zwei globale Variablen, die in main
deklariert sind. Soweit funktionert das auch.
In main sind die Variablen wie folgend deklariert:
1
unsignedintSTabelle[33];
2
unsignedintWTabelle[33];
In den anderen *.c Files natürlich mit dem Zusatz
1
extern...
Da die Variablen Arrays sind möchte ich jetzt nur einmal die Größe
ändern, damit das dann überall übernommen wird. Sonst müsste ich ja in
jedem File die Größe wieder manuell ändern.
Dachte mir ich mach ne *.h File und schreib folgendes rein:
1
#define STSIZE 28
2
#define WTSIZE 28
Diese includiere ich dann in jeder Datei und schreib bei meinen globalen
Variablen
1
unsignedintSTabelle[STSIZE];
2
unsignedintWTabelle[WTSIZE]
Nur bekomm ich immer beim compilieren einen "syntax error". Und gemeint
ist die Zeile, in der ich die Variablen deklariere.
Kann mir jemand dabei helfen?? Trotz alledem, dass ich die h-Datei mit
den #defines inkludiert habe, übernimmt der Compiler nicht die Werte an
den Platz, wo sie hinsollen.
Bin für jeden Tip dankbar.
MfG Darkleon
Kann nicht sein, was du machst ist eigentlich korrekt. (Abgesehen davon,
dass du die 'extern'-Deklarationen eigentlich auch noch in den Header
packen könntest, spart Tipparbeit)
Also:
1. genaue Fehlermeldung posten
2. vollständigen Quelltext zeigen.
Also meine H- Datei heißt "PICsetup.h"
Da drin steht folgendes:
1
#define STSIZE 28
2
#define WTSIZE 28
Die main sieht folgendermaßen aus (der relevante Teil):
1
#include"PICsetup.h"
2
#include<p18f4550.h>
3
4
//PUBLIC VARIABLES//
5
unsignedintSTabelle[STSIZE];
6
unsignedintWTabelle[WTSIZE];
7
8
/******PROCEDURE ********/
9
voidmain(void)
10
{
11
12
}
Die Fehlermeldung (MPLAB V8.30)
main.c:12:Error: syntax error
Ich weiß eben auch nicht mehr weiter, wieso der Compiler die defines
nicht übernimmt, denn in den Einstellungen sind die "Inlcude" Pfade
richtig angegeben..
MfG
Darkleon schrieb:
> Die Fehlermeldung (MPLAB V8.30)> main.c:12:Error: syntax error
Kommt die Fehlermeldung tatsächlich bei der schließenden Klammer von
Main?
Kommentiere mal versuchsweise die ganze main aus und compiliere. Wenn
der Fehler dann weg ist, gefällt ihm die main nicht.
(Du wirst dann zwar einen Linkerfehler bekommen, aber das ist erst mal
egal.)
skorpionx schrieb:
> extern unsigned int *STabelle;> extern unsigned int *WTabelle;
Damit werden die Arrays zwar deklariert, aber nicht definiert. Das endet
dann mit einem Linkerfehler...
>Damit werden die Arrays zwar deklariert, aber nicht definiert. Das endet>dann mit einem Linkerfehler...
Hier sind die schon definiert:
//PUBLIC VARIABLES//
unsigned int STabelle[STSIZE];
unsigned int WTabelle[WTSIZE];
/******PROCEDURE ********/
void main (void)
{
}
skorpionx schrieb:
>>Damit werden die Arrays zwar deklariert, aber nicht definiert. Das endet>>dann mit einem Linkerfehler...>> Hier sind die schon definiert:
Dann mußt du mal erklären, was du mit deinem Posting oben gemeint hast.
>Ich programmiere in C für einen PIC 18F4550. Ich habe mehrere *.c Files...
Die Variablen dürfen nur in einem File definiert werden und in anderen
mit dem zusatz extern deklariert.
Dem Compiler stört das bei der externem deklkarationen noch die
Grösse (STSIZE...)steht.
alex schrieb:
> Bei "void main" meckert der Compiler nicht? Sollte es nicht "int main"> sein?
Eigentlich sollte main() einen Rückgabewert haben. Auch wenn das bei
Embedded-Programmierung mit der typischen Endlosschleife nicht so
richtig Sinn ergibt.
sieh dir mal die Schreibweise fürs Define an.
Es gibt da zwischen den Compilern unterschiede.
Einige wollen ein "=" vor dem Wert, es gibt auch die Variante mit ";" am
Ende.
Sollte aber in der Beschreibung des Compilers stehen.
Ralph schrieb:
> sieh dir mal die Schreibweise fürs Define an.> Es gibt da zwischen den Compilern unterschiede.> Einige wollen ein "=" vor dem Wert, es gibt auch die Variante mit ";" am> Ende.
Wenn es ein C-Compiler ist, dann bestimmt nicht. Die Syntax der
#define-Direktiven ist korrekt.
Ich tippe darauf, daß der Compiler sich an der Signatur von main stört.
Das quittieren manche mit einem Syntaxfehler, andere tolerieren es.
Daß der Fehler offenbar bei der schließenden Klammer von main kommt,
deutet darauf, daß er sich an main verschluckt hat.
Hallo!
Also der Compiler mekert nicht bei main, sondern bei der Deklaration von
1
unsignedintSTabelle[STSIZE];
Ich habe ja in der Header Datei "nur" STSIZE definiert und den Wert
zugewiesen. Die eigentliche Variablendefinition ist die, die kurz vor
main steht.
In den anderen Source Dateien sind die globalen Variablen natürlich mit
"extern" gekennzeichnet.
Wenn ich die globalen Variablen in der Header Datei definiere. Also nach
1
#define STSIZE 26
2
[c/]
3
kommtdann
4
[c]
5
unsignedintSTabelle[STSIZE];
und in main diese auch extern angebe, dann mekert er auch bei der
gleichen Zeile....
Keine Ahnung was da schief läuft..
MfG
Hab die main auskommentiert, und jetzt bringt der Compiler folgendes:
Error [1105] symbol 'STSIZE' has not been defined
Error [1219] integer constant expected
Error [1105] symbol 'WTSIZE' has not been defined
Error [1219] integer constant expected
Als ich ohne diesen Versuch mein Programm kompiliert habe, also mit
1
unsignedintSTabelle[26]
2
unsignedintWTabelle[26]
hat alles funktioniert. Nur fand ich es eben als lästig, dass ich in
jedem c-file den Wert ändern musste, wenn z.B.: das Array um ein Feld
vergrößert werden musste.
Deshalb wollte ich das eigentlich jetzt nur einmal definieren und alle
c-files (inkl.main) bekommen den neuern Wert von der Header Datei.
Aber das will nicht wirklich...
MfG
Noch als Zusatz:
Benutz den C18-Compiler. Hatte mit
1
voidmain(void)
noch nie Probleme.
Wenn ich
1
intmain(void)
angebe, dann bringt mir der Compiler folgendes:
Warning [2103] default startup code expects main function declared as
'void main (void)'
Aber wie schon gesagt, an der main liegt es nicht. Irgendwo gibts
Probleme die defines an die richtige Stelle zu stellen.
MfG
Poste mal die .c und .h Files. Es ist bestimmt irgendwas saudummes, was
man so nicht sieht. C-Compiler sind zuweilen etwas hinterhältig...
Was du noch machen kannst: Sieh mal nach, ob der Compiler eine Option
hat, mit der man die Ausgabe des Preprocessors auf Datei ausgeben kann.
Dann siehst du, was aus deinen #defines geworden ist.
>Die Fehlermeldung (MPLAB V8.30)>main.c:12:Error: syntax error
1) Zeile 12 ist die schließende Klammer von main??
2) es reicht wenn du in einem File die arrays definierst
und im anderen mit
extern int array[]
deklarierst, da brauchts keine Größenangabe. Feldgrenzen werden ja weder
vom Compiler noch zur Laufzeit überprüft
>Error [1105] symbol 'STSIZE' has not been defined
3) dann versuch doch mal das define direkt vor die Definition in den
main.c File zu schreiben
Im Post 3 hab ich schon alles hergezeigt :) Mehr besteht nocht nicht, da
ich das komplette Projekt erst angefangen hab und die c-files schon
vorher geschrieben hab.
Wenn ich es so schreib
1
#include"PICsetup.h"
2
#include<p18f4550.h>
3
4
#define STSIZE 28
5
#define WTSIZE 28
6
7
//PUBLIC VARIABLES//
8
unsignedintSTabelle[STSIZE];
9
unsignedintWTabelle[WTSIZE];
10
11
/******PROCEDURE ********/
12
13
voidmain(void)
14
{
15
16
}
dann compiliert er alles und gibt das OK. Nur wäre dann die PICsetup.h
sinnlos und die defines wären dann für die anderen c-files wieder
unsichtbar. Das heißt ich müsste die wieder überall definieren und hätte
überhaupt keine "Erleichterung".
Ich kann zwar nichts zur Lösung beitragen, aber deine Vorgehensweise ist
imho absolut korrekt.
Beispiel:
in der STDLIB.H eines alten DOS-Compilers steht z.B.
1
#define _MAX_PATH 260 /* max. length of full pathname */
2
#define _MAX_DRIVE 3 /* max. length of drive component */
3
#define _MAX_DIR 256 /* max. length of path component */
usw.,
und diese Konstanten können in jedem Modul verwendet werden - genauso
wie du es machst.
Einzig die Tatsache, dass deine Include-Datei nicht bei den
System-Includes steht, ist ein Unterschied.
Probier doch mal mit einer Kopie deiner PICsetup.h im entsprechenden
Verzeichnis diese Variante:
#include <PICsetup.h>
Alternativ könnte noch ein im Editor nicht sichtbares Sonderzeichen in
den beiden #define-Zeilen stören - habe ich auch schon erlebt.
PS. Ich bin nur Gelegenheitsprogrammierer für eigene, kleine
Hilfsmittelchen :-)
C12 ist schon die Zeile, wo "STabelle" definiert wird. Hab nur die
Leerzeilen und Kommentare hier im Forum weggelöscht.
Also das mit der deklaration "extern unsigned int STabelle[]" wusste ich
noch nicht, zumindest nicht mit der leeren Klammer. Sonst sind die
Arrays in jedem file, die die benötigt mit extern gekennzeichnet.
Das muss ich gleich mal versuchen...
MfG
Darkleon schrieb:
> Im Post 3 hab ich schon alles hergezeigt :) Mehr besteht nocht nicht, da> ich das komplette Projekt erst angefangen hab und die c-files schon> vorher geschrieben hab.
Das ist wie gesagt was saudummes und wenn du die Orginalfiles nicht
posten willst, mußt du eben selbst suchen.
@ uhu
Wie gesagt, mehr gibts noch nicht. ich hab nicht mal die c-files in das
Projekt inkludiert. Wollte das eben nur mal mit den #define's versuchen,
da ich mir dadurch einiges an Schreibarbeit ersparen könnte.
MfG
uhu, ich weiß nicht, was du jetzt hast?
Ich hab alles geschrieben, und mehr besteht noch nicht. Hab noch keine
Source Dateien dem Projekt hinzugefügt und bei main mekert der Compiler
wegen der Definition.
Mehr gibts auch nicht, dazu braucht man keine Glaskugel....
Das mit den leeren Klammern funktioniert :) Werd das Projekt jetzt mal
zusammenstellen und dann schauen ob alles passt ;)
Hab auch versucht die "PICsetup.h" in den "Include"-Ordner zu opieren
und mit < > einzubinden, aber da ensteht der gleiche Fehler, der schon
von Anfang an war.
Jetzt versuch ich mal alles mit den [] zu machen und schau, ob das dann
funktioniert. Das wäre ja im Grunde die gleiche Sache, die ich mit den
defines vorhatte:)
Nochmals Danke an alle für die schnelle und informative Hilfe.
Wünsche allen schon mal eine gute Nacht :D
Nochmals Danke!!!
Mfg Darkleon
@ Darkleon
Was ich habe? 25 Jahre Erfahrung mit C.
Du wärst nicht der Erste, der meint alles richtig gemacht zu haben und
trotzdem eine Fußangel in seinem Quelltext hat, die man aus zweiter Hand
nie findet.
ist zwar schön dass dir mein Tipp mit den leeren Klammern hilft,
aber das ist nur kurzfristig bis du wieder Mal ein define brauchst
Was Uhu meint ist die 2 betreffenden Dateien als Anhang zu posten damit
man wirklich sieht was drin steht.
Das würde Dir auch langfristig mmehr helfen
Häng doch bitte mal in der Include-Datei mit den beiden #defines drin
eine leere Zeile am Ende an.
Alter Anfängerfehler! #include ist eine reine Textersetzung.
Also eine include-Datei test.h mit folgendem Inhalt:
#define TEST 10 (ohne Zeilenende hier!)
included in folgende Sourcecodedatei
#include <test.h>
void main()
wird nach dem Preprozessor zu:
#define TEST 10 void main()
und schon hast Du Deinen Syntax error.
Gruß
WM
Wolfgang Mües schrieb:
...
> Alter Anfängerfehler! #include ist eine reine Textersetzung.>> Also eine include-Datei test.h mit folgendem Inhalt:>> #define TEST 10 (ohne Zeilenende hier!)>> included in folgende Sourcecodedatei>> #include <test.h>> void main()>> wird nach dem Preprozessor zu:> #define TEST 10 void main()
Auch beliebt:
moin
vermutung von mir, deine PICsetup.h wird nicht angezogen. sollte
eigentlich ein Warning schmeissen "Include not found" oder so. also die
log ausgabe noch mal genau anschauen, ggf das loglevel / warning level
des compilers hochschrauben.
Uhrsache für die nichtgefundene PICsetup.h falscher oder fehlender
Include path. falsche schreibweise, mehrer solcher dateien, und es wird
die falsche angezogen.
alternative falsch gesetzte Includ gards aber ich vermute mal das die
noch gar nicht drinnen sind.
Ist es wirklich ausgeschlossen, dass das in deinem Setup direkt an den
Compiler, unter Umgehung des Präprozessors, geht?
Sonst jag es doch erstmal durch den Prä und guck Dir an was wirklich
hinten rauskommt...
Prüf doch mal nach ob am Ende jeder Datei (also nicht nur die Header,
auch und vor allem die C-Files) eine neue, leere Zeile steht. Ist eine
Weile her das ich mit dem C18 gearbeitet habe, aber ich meine mich zu
erinnern das der bei diesen Sachen sehr zickig sein konnte.
Sollte in deinem Fall eigentlich keinen Unterschied machen, aber wer
weiß. Ist auch logischer so: Zuerst wird das System definiert, dann
kommen deine eigenen Deklarationen und dann geht der Code los.
Hallo!
@MeinerEiner
Danke, aber ich weiß schon wie man Dateien anhängt. Keine Sorge..
Also ich hab gestern noch versucht die beiden Dateien auf einem anderen
Rechner zu compilieren. Und da hats funktioniert.
Hab jetzt auf diesem Rechner das Projekt nochmals neu angelegt (mal nur
mit diesen zwei Dateien) und nun funktionierts auch hier ?!? Keine
Ahnung wieso das alte Projekt so gezickt hat.
Dachte mir ich kapier die defines in C überhaupt nicht mehr ;)
Hab die beiden Dateien angehängt. Hab eigentlich nichts verändert, nur
wie gesagt ein neues Projekt erstellt.
Nochmals Danke an alle für die schnelle und kompetente Hilfe!
MfG Darkleon
Datentypen definiert man normalerweise nicht mit #define sondern mit
typedef. Müsste sich zwar aufs gleiche rausgehen, wenn der Precompiler
das ersetzt, aber drauf verlassen würd ich mich nicht.
Hi uhu!
Danke für den Tip, aber wieso es intelligenter ist "do..while" zu
verwenden versteh ich jetzt nicht ganz.
Init() kommt bei mir nur einmal ganz am Anfang von main vor, damit die
Register gesetzt werden. Das mache ich nicht von einer Bedingung
abhängig.
Hab mir diesen Stil wahrscheinlich von microchip abgeschaut, da die das
auch immer in ihren Projekten verwenden. Wenn ich einfach das setzen der
Bits an den Anfang von main schreibe ist es sicherlich einfacher, da der
weg über #define nicht gemacht wird.
Aber nochmals zu Deinem Vorschlag. Die Schleife wird ja nur einmal
durchlaufen, da ja die Bedinung in while nicht stimmt, oder? Kannst Du
mir sagen, wieso das so sinvoller wäre? Lerne ja gerne dazu:)
MfG Darkleon
Du schreibst in deinem Headerfile:
#define STSIZE 28
#define WTSIZE 28
Ich würde mal schreiben:
const int STSIZE = 28;
const int WTSIZE = 28;
Es sind Konstanten. Es sind Integer-Werte.
Das ist es doch, was doch brauchst, oder?
Darkleon schrieb:
> Danke für den Tip, aber wieso es intelligenter ist "do..while" zu> verwenden versteh ich jetzt nicht ganz.> Init() kommt bei mir nur einmal ganz am Anfang von main vor, damit die> Register gesetzt werden. Das mache ich nicht von einer Bedingung> abhängig.
Defines schreibt man häufig in Headerfiles und die guckt man dan i.d.R.
nicht mehr so oft an. Dann erinnert man sich, daß es eine Funktion XYZ()
gibt, die was bestimmtes macht, das man mal eben brauchen kann, wenn
eine bestimmte Bedinung erfüllt ist... und schon ist es passiert: Mein
Programm macht was, was völlig unmöglich ist und ein paar Stunden
Fehlersuche.
Und das nur, weil man beim Verfassen dieses Macros mal wieder nicht vom
Daumen zum Zeigefinger gedacht hat...
Das Problem ist, daß man bestrebt ist, ausgetesteten Code
wiederzuverwenden, um sich die Zeit zu sparen, die entsprechende
Funktionalität nochmal zu implementieren.
Wenn solcher wiederverwendeter Code unsauber geschrieben ist, kann man
böse Überraschungen erleben...
> Aber nochmals zu Deinem Vorschlag. Die Schleife wird ja nur einmal> durchlaufen, da ja die Bedinung in while nicht stimmt, oder? Kannst Du> mir sagen, wieso das so sinvoller wäre? Lerne ja gerne dazu:)
Ja, aber der Unterschied ist eben, daß mit dem do ... while unter einem
if der gesamte Block bedingt ausgeführt wird, während ohne das do ...
while nur das erste Statement des #defines bedingt und der Rest
unbedingt ausgeführt wird und man das dem Aufruf nicht ansieht.
#defines werden vom Preprozessor abgearbeitet, bevor der Compiler den
Quelltext sieht. Wenn der den Namen eines definierten Symbols erkennt,
dann kopiert er an seiner Stelle - evtl. nach einer textuellen
Parametersubstitution - den Text aus dem #define ein.
Dieses do ... while(0) ist ein Trick, um den definierten Text
syntaktisch als Statement zu verpacken und damit eine tückische
Fehlerquelle zu beseitigen, die sich bei Benutzung des Preprozessors
gerne unbemerkt einschleicht.
Es gibt Programmierer, die von der Benutzung von #define wegen solcher
Fallstricke generell abraten. In der Tat könntest du in deinem Beispiel
auch sehr gut ohne auskommen:
Die Konstanten kann man als enum-Tags (z.B. in einen Header) schreiben:
1
enum{STSIZE=28,WTSIZE=28};
Dein INIT() kannst du, ohne dir irgendwas zu vergeben, als normale
Funktion schreiben. Viele moderne C-Compiler kopieren kleine
parameterlose Funktionen am Aufrufort als Maschinencode ein, statt sie
per call aufzurufen.
Wie MeinerEiner oben schon geschrieben hat, kann man Datentypen per
typedef definieren. Du kannst also wirklich ohne #define zurecht kommen.
Nachtrag: Die modernere (C++?) Variante der enum-Methode ist die von Mr
Tannnoy oben beschriebene.
>Es sind Konstanten. Es sind Integer-Werte.>Das ist es doch, was doch brauchst, oder?
Schon, aber die brauchen dann auch extra Speicherplatz auf dem Target.
Bei #define wird der String 'STSIZE' durch den String '28' beim
Preprocessing ersetzt.
Er hat es durchaus sinnvoll gemacht und das Problem war ja auch gelöst -
leider ohne dass man die Ursache genau ergründen konnte.
HildeK schrieb:
> Schon, aber die brauchen dann auch extra Speicherplatz auf dem Target.> Bei #define wird der String 'STSIZE' durch den String '28' beim> Preprocessing ersetzt.
Zumindest C++ reserviert keinen Speicherplatz dafür. Ob C das auch so
macht, weiß ich im Moment nicht.
Uhu Uhuhu schrieb:
> HildeK schrieb:>> Schon, aber die brauchen dann auch extra Speicherplatz auf dem>> Target. Bei #define wird der String 'STSIZE' durch den String '28'>> beim Preprocessing ersetzt.>> Zumindest C++ reserviert keinen Speicherplatz dafür.
Sofern es der Compiler wegoptimiert. Der GCC tut dies von -O1 aufwärts.
> Ob C das auch so macht, weiß ich im Moment nicht.
In C hat das 'const' eine andere Bedeutung wie in C++, da geht das
gewünschte Konstrukt
1
constintn=5;
2
inta[n];
für statische a überhaupt nicht. Deswegen nimmt man in C für Konstanten
meist Makros, während in C++ mit const definierte Konstanten der bessere
Stil sind. Der Enum-Trick geht in beiden Sprachen, ist aber eher ein
Hack, da Enums, wie der Name schon andeutet, eigentlich für ganz andere
Dinge vorgesehen sind.
moin
eine konstante variable sollte auf jedem C / C++ compiler eine Datenwort
im Konstant area der ausgabe datei erzeugen. das bedeutet, das die
Konstante
1. Speicherplatz im konstant area der ausgabe datei belegt, sollte in
der map datei ersichtlich sein
2. dadurch eine indirekte addressierung ausgelöst werden kann. ein
register wird nicht direkt mit dem wert initallisiert, sondern erst der
wert von der adresse gelesen. dauert somit länger
3. gefahr das const mal zu vergessen, oder falsch zu setzen. ändert
nichts am ablauf des Programmes, nur ist das dann eine vorinitallisierte
variable, die zur laufzeit geändert werden kann, und beim startup erst
initallisiert werden umss.
kann durch aus sein, dass kompiler das wegoptimieren können. nur ob man
darauf vertrauen kann, ...
und zu dem lustigen do while(0) konstuckt.
Init2 sollte auch ohne du while(0) geraffel genau das gleiche bewirken.
ausnahme. der kompiler ist dermassen verkorkst, das er das mit den {}
nicht sauber gebacken bekommt.
oder man läst kein if,else, ... ohne ein nachfolgendes{} stehen. mach
ich selbst wenn ich nur ner variable bedingt eine konstante zuweise.
1
if(doInit)
2
{
3
init2();
4
}
5
6
if(a!=b)
7
{
8
x=a;
9
}
10
else
11
{
12
x=b;
13
}
14
15
x=(a!=b)?a:b;// macht das gleiche nur ohne if else
termite schrieb:
> moin>> eine konstante variable sollte auf jedem C / C++ compiler eine Datenwort> im Konstant area der ausgabe datei erzeugen. das bedeutet, das die> Konstante> 1. Speicherplatz im konstant area der ausgabe datei belegt, sollte in> der map datei ersichtlich sein> 2. dadurch eine indirekte addressierung ausgelöst werden kann. ein> register wird nicht direkt mit dem wert initallisiert, sondern erst der> wert von der adresse gelesen. dauert somit länger> 3. gefahr das const mal zu vergessen, oder falsch zu setzen. ändert> nichts am ablauf des Programmes, nur ist das dann eine vorinitallisierte> variable, die zur laufzeit geändert werden kann, und beim startup erst> initallisiert werden umss.
Dir ist bekannt, daß weder C noch C++ dynamische Arrays kennt? Falls für
eine const-Variable in C++ Speicher allokiert wird - was ich nicht
glaube - dann wird dessen Inhalt garantiert nicht für die Bestimmung von
Arraygrenzen benutzt.
> und zu dem lustigen do while(0) konstuckt.>
>> Init2 sollte auch ohne du while(0) geraffel genau das gleiche bewirken.> ausnahme. der kompiler ist dermassen verkorkst, das er das mit den {}> nicht sauber gebacken bekommt.>> oder man läst kein if,else, ... ohne ein nachfolgendes{} stehen. mach> ich selbst wenn ich nur ner variable bedingt eine konstante zuweise.>
1
>if(doInit)
2
>{
3
>init2();
4
>}
Und genau hier ist der Knackpunkt: init2() sieht aus, wie ein
Funktionsaufruf, ist aber keiner - genau dieses Wissen hast du genutzt,
als du schnell einen Block drumrum geschrieben hast...
Die Erfahrung sagt, daß schon nach relativ kurzer Zeit solche
Implementierungsdetails nicht mehr unbedingt präsent sind und bei der
nächsten Änderung rasselt irgendeiner in diese Falle und keiner merkts,
bis irgendwas Schlimmes passiert. Dann kann man sich dumm und dämlich
debuggen, weil derlei Fehler nur im ASM-Modus des Debuggers
nachzuvollziehen sind.
Hi!
@ Mr Tannnoy
Wenn ich Deinen Vorschlag benutze, so erzeuge ich ja zwei neue
Variablen, die wieder Speicherplatz benötigen, oder? Vor allem will ich
ja zur Laufzeit die Arraygröße nicht ändern.
Im Grunde will ich nur die Arraygröße einmal angeben müssen (in der
Header Datei) und alles Funktionen wissen bescheid, wie groß die beiden
Arrays sind und können damit arbeiten. Wie groß diese tatsächlich sind
weiß ich jetzt eben noch nicht, denn während der programmierung kann
sich noch vieles ändern (andere Sichtweise, neue Ideen, usw..)
Daher hab ich das mit define gelöst.
Dass ich auch die globalen Variablen in einer Headerdatei anlegen und
dann in der jeweiligen Funktion inkludieren kann wusste ich bis jetzt
noch nicht :) (Bin ja noch ziemlich am Anfang mit C und kenn daher die
Tricks noch nicht). Ich glaub so werd ich das auch machen, da ich sie
dann nur einmal ändern muss, und falls ich statt "int" ein "char" Array
benutze (wegen Speicherplatz) brauch ich das so ja auch nur einmal
ändern:) zu 90 Prozent muss ich nur Statusbits (0-1) ablegen, aber C
kennt leider den Datentyp "boolean" nicht. Sensoren usw arbeiten dann
auch mit 8-Bit Auflösung und das genügt für mein Vorhaben locker aus.
Deshalb wollte ich das alles so schnell wie möglich geändert haben.
Alles andere hier ist mir noch leider etwas zu hoch (die letzten
Beiträge von uhu, yalu, usw..) aber ich lerne gerne dazu. (will mich ja
mal wirklich auskennen, was ich mache und was es für Möglichkeiten
gibt).
Nochmals Danke an alle!!
Ihr habt mir wirklich super weitergeholfen und mir viele Verbesserungen
gezeigt.
MfG Darkleon
C kennt sehr wohl einen Boolean-Datentyp, ab C99. Der taugt allerdings
wenig zum Speicherplatz sparen, denn er belegt normalerweise einen
'int'.
C kennt auch 'dynamische' Alloziierung, zumindest in diesem Sinne:
Sven P. schrieb:
> C kennt sehr wohl einen Boolean-Datentyp, ab C99. Der taugt allerdings> wenig zum Speicherplatz sparen, denn er belegt normalerweise einen> 'int'.>> C kennt auch 'dynamische' Alloziierung, zumindest in diesem Sinne:>
1
>size_tlen=strlen(irgendein_string);
2
>charstring_kopie[len+1];
3
>memcpy(string_kopie,irgendein_string,len+1);
4
>
Den Code hast du aber garantiert noch nichtmal compiliert... Wir hatten
es von Arrays im Sinn von
1
intarray[5];
Die sind und bleiben unveränderlich und die Arraygrenze wird zur
Laufzeit implizit in den Stack-Allokierungscode eingebaut, bzw. für
globale Arrays nur in einem Datensegment reserviert und nacher nicht
mehr verwendet, es sei denn, man hat sie irgendwo definiert, oder
berechnet sie explizit, z.B. durch Konstruktionen wie diese:
1
#define arraysize(x) (sizeof x / sizeof x[0])
Im Übrigen ist von der Benutzung von dynamischen Speicherbereichen auf
kleinen µCs unbedingt abzuraten.
at Uhu Uhuhu:
bei der statischen definition von arrays wo es hier ja darum ging, ist
das richtig. da dies ja schon zu kompilzeit definiert wird.
trotzdem ist es eine Variable, die selbst wenn sich nicht weiter benutzt
wird. erst der linker kann dann entscheiden, ob er sie haben will oder
nicht.
die Konstante für die Arraygrösse wird wenn man sie schon mal hat
meistens auch noch für andere sachen verwendet, als nur für
Arraydefinition: schleifen bedingungen, Ich hab da wohl etwas
weitergedacht als nur bis zur definition.
1
constunsignedintBUFFER_LENGTH=255u;
2
3
unsignedcharbuffer[BUFFER_LENGTH];
4
5
for(i=0;i<BUFFER_LENGTH;i++)
6
{
7
buffer[i]=i;
8
}
und zum init2(). auch im macro ist ein block definiert. ich hab es im
prinzipt doppelt abgesichert. einaml beim IF einmal im macro. das do
while(0) emfinde ich für überflüssig, ausser es hatte einen speziellen
grund, damit die block klammern nicht vom präprozessor oder sonst
jemanden verschluckt werden.
das gleiche gilbt eigentlich auch für normale defines. die sollten auch
geklammert werden.
1
#define HEAD 5
2
#define STRUKTSIZE 40
3
#define BUFFER1 HEAD + STRUCTSIZE /* kann zu fehlern führen */
termite schrieb:
> und zum init2(). auch im macro ist ein block definiert. ich hab es im> prinzipt doppelt abgesichert. einaml beim IF einmal im macro. das do> while(0) emfinde ich für überflüssig, ausser es hatte einen speziellen> grund, damit die block klammern nicht vom präprozessor oder sonst> jemanden verschluckt werden.
Die Idee zu dem do ... while(0)-Trick ist, aus dem Macro-Rumpf ein
Statement zu machen, nicht ein Compoundstatement. Damit hat es
syntaktisch dieselben Eigenschaften, wie der Aufruf einer void-Funktion.
Die Methode ist übrigens eine schon ziemlich alte Empfehlung des
C-Normierungskommitees.
> das gleiche gilbt eigentlich auch für normale defines. die sollten auch> geklammert werden.>>
1
>#defineHEAD5
2
>#defineSTRUKTSIZE40
3
>#defineBUFFER1HEAD+STRUCTSIZE/* kann zu fehlern führen */
Genau. Der Preprozessor bietet viele Möglichkeiten, Fehler einzubauen,
die man dem Quelltext nicht auf Anhieb ansieht. Deswegen ist es gut,
sich beizeiten einige Vorsichtsmaßnahmen anzueignen, wenn man Macros
schreibt.