Forum: Compiler & IDEs #defin - als Char und String..


von Oliver R. (roliver)


Lesenswert?

Hallo in die Rund,

ich bin grade auf der suche nach einer Lösung, doch der Google konnte 
mir jetzt auch noch nicht helfen.

ich würde gerne mit einem #define ein Programm flexibel machen.
1
#define EINZEICHEN 'a'
2
..
3
void lcdouts (const char *s)
4
{ machwas };
5
..
6
char zeichen;
7
#ifdef 
8
 zeichen = EINZEICHEN;
9
#else
10
 Zeichen = 'x';
11
#ifend

soweit ok, doch jetzt benötige ich das Zeichen noch mal zur Ausgabe
1
lcdouts ("Hallo"); # OK
2
lcdouts ("INIT:"EINZEICHEN); # Fehler

Kann da mir jemand helfen?

Gruss

Oliver


PS.: Meine c Kenntnisse sind noch in den Kinderschuhen...

von Markus M. (mark_m)


Lesenswert?

Lese dich über C-Strings ein und den String Funktionen aus string.h.
1
/* Angabe fuer 16 Zeichen LCD + '\0' */
2
#define LCD_ZEILEN_LAENGE 16+1
3
4
/* Array fuer den Zusammenbau der LCD-Zeile */
5
char lcdText[LCD_ZEILEN_LAENGE];
6
/* Das Zeichen 'a' als C-String initialisieren */
7
char einzeichen[] = "a";
8
9
strcpy( lcdText, "Hallo" )
10
lcdouts( lcdText );
11
strcpy( lcdText, "INIT:" );
12
strcat( lcdText, einzeichen);
13
lcdouts( lcdText );

Ausserdem mache dir klar, was der Preprozessor erledigt und was das 
C-Programm. Der Preprozessor bearbeitet den Programmtext bevor der 
Compiler diesen zu sehen bekommt. Du kannst mit dem Preprozessor nur 
steuern was Kompiliert werden soll aber nicht den Programmablauf 
beeinflussen.

Grüsse

von PittyJ (Gast)


Lesenswert?

Mit #define kann man sehr viel Blödsinn anstellen, da es die Struktur 
eines Programmes verändern kann.

Anfängern würde ich empfehlen, auf #define zu verzichten, bevor sie 
verstehen, was sie wirklich machen.

Modere Compiler haben auch const Konstanten, mit denen man gut feste 
Werte definieren kann.

von Rolf M. (rmagnus)


Lesenswert?

Oliver R. schrieb:
> lcdouts ("INIT:"EINZEICHEN); # Fehler

Der Preprozessor hat damit an sich erstmal nichts zu tun. Er macht aus 
dem obigen folgendes:
1
lcdouts ("INIT:"'a'); # Fehler
und das ist nicht zulässig. Man kann zwar zwei Strings konkatenieren, 
etwa in der Art:
1
lcdouts ("INIT:""a");
aber nicht einen String und einen int ('a' ist vom Typ int).

Wenn du aber "a" statt 'a' schreibst, geht das hier natürlich nicht 
mehr:

Oliver R. schrieb:
> zeichen = EINZEICHEN;

Du könntest dann höchstens schreiben:
1
zeichen = *EINZEICHEN;
aber das finde ich eher unschön.

Markus M. schrieb:
> Du kannst mit dem Preprozessor nur steuern was Kompiliert werden soll
> aber nicht den Programmablauf beeinflussen.

Ich sehe nicht, daß er irgendwo einen Programmablauf steuern will, 
sondern lediglich ein zur Compilezeit vorgegebebes Zeichen an einen 
ebenfalls zur Compilezeit vorliegenden String anhänhen will, und das 
vermutlich ohne diese Aktion erst umständlich zur Laufzeit machen zu 
müssen.

von Oliver (Gast)


Lesenswert?

Rolf Magnus schrieb:
> und das
> vermutlich ohne diese Aktion erst umständlich zur Laufzeit machen zu
> müssen.

Und das geht per Preprozessor halt nicht.
Wobei nicht auszuschliessen ist, daß der Compiler bei Nutzung der 
Standard-String-Funktionen das zur Compilezeit macht.

Oliver

von Oliver R. (roliver)


Lesenswert?

Hallo

zu Markus M.:

ich habe schon verstanden, das der Preprozessor nix in der Laufzeit 
ändert, sonder nur den Code.
Und das Wolle ich ja.

Also ich habe mit dem Char (zb. 'a')) eine Adresse in eimen Master/Slave 
Bus definert.

Jetzt wolle ich zum einen diese Adresse als Char verwenden und zum 
anderen zur Ausgabe so:
1
#nur als Beispiel.
2
#
3
#define ADRSLC 'a'
4
5
#initSlave(Char x)
6
initSlave(ADRSLC);
7
8
#LCD ausgabe
9
lcdprints ("Meine ADR:"ADRSLC);
10
11
12
#Verabeitung der Adresse
13
if(strcmp(buffer, ADRSLC"lmx01") == 0)
14
{ mach eins }
15
if(strcmp(buffer, ADRSLC"lmx01") == 0)
16
{ mach zwei }

so und wie man sieht habe ich die Adresse an vielen stellen und ich 
wollte sie So dymisch machen, so das ich das Programm in X Atmel nutzten 
kann.

Gruß

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Naja, wie Rolf schon schrieb, wenn du das so umbauen kannst, dass
du schreibst:
1
#define ADRSLC "a"

dann funktionieren all die String-Operationen bereits.  Du müsstest
allerdings deine Funktion initSlave() dann umbauen.  Statt:
1
void initSlave(char c)
2
{
3
   dosomething = c;
4
}

müsstest du schreiben:
1
void initSlave(const char *s)
2
{
3
  dosomething = s[0];
4
}

von Oliver R. (roliver)


Lesenswert?

Hallo,

Danke an Rolf und Jörg, es geht.
Ob schön weis ich nich nicht aber es geht.

und zwar:
1
#define ADRMY "x"
2
...
3
# in Include file
4
5
#ifdef ADRMY
6
  if (data == ADRMY[0])
7
#else
8
  if (data == 'c')
9
#endif
10
11
#in Main
12
if(strcmp(buffer, ADRMY"lmx01") == 0)        
13
{
14
  rs485_puts('a', ADRMY"01OK\n");  
15
  bout = 1;
16
};
17
if(strcmp(buffer, ADRMY"lmx02") == 0)
18
{
19
  rs485_puts('a', ADRMY"02OK\n");
20
  bout = 2;
21
};
22
... // und so weiter..

also Danke ;-)

BTW: wie bau ich den die if ind switchs um?

Gruß

Oliver

von troll (Gast)


Lesenswert?

Oliver R. schrieb:
> BTW: wie bau ich den die if ind switchs um?
Man kann in C keine Strings per switch vergleichen...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.