tausch()
-
#define tausch(a,b) {char *c=a; a=b; b=c;}
Das ist natürlich C89 und auch C99 und auch K&R-C. Aber an diesem Beispiel kann man gut ein anderes Problem beobachten, das mit Makros in den meisten Sprachen besteht. Nämlich der Name der temporären Variable
c
. Wenn einer der beiden Parameter schonc
heisst, kommt man in Schwierigkeiten.Man könnte versuchen, Abhilfe zu schaffen, indem man einen möglichst unwahrscheinlichen Namen statt
c
nimmt, aber das ist offensichtlich keine Lösung. Aus dem Grund ist es ganz allgemein besser, für solche Fälle Inline-Funktionen zu nehmen, dazu hätte es gereicht, dem Vorschlag von Torben eininline
voranzustellen. Andernfalls müsste man ein Makrosystem einführen, das garantiert unbenutze Symbole generieren kann.
-
ja habs verstanden, das euch ein xor-swap auf ints und pointer im speziellen nicht gefällt
-
aus der coder hölle schrieb:
ja habs verstanden, das euch ein xor-swap auf ints und pointer im speziellen nicht gefällt
Es geht nicht darum, ob es uns gefällt, sondern ob wir annehmen dürfen, dass ein C-Compiler sowas in ein lauffähiges Programm übersetzen kann. Mit zwei int's wäre das kein Problem, denn Each of the operands shall have integer type.
-
µngbd schrieb:
#define tausch(a,b) {char *c=a; a=b; b=c;}
Das ist natürlich C89 und auch C99 und auch K&R-C. Aber an diesem Beispiel kann man gut ein anderes Problem beobachten, das mit Makros in den meisten Sprachen besteht. Nämlich der Name der temporären Variable
c
. Wenn einer der beiden Parameter schonc
heisst, kommt man in Schwierigkeiten.Dann mach es so:
#define tausch(a,b) {char *v##__LINE__=a; a=b; b=v##__LINE__;}
-
logisch, ne? schrieb:
Dann mach es so:
#define tausch(a,b) {char *v##__LINE__=a; a=b; b=v##__LINE__;}
Schlaue Idee. Leider kann es immer noch eine Variable geben, die v123 heisst, wenn die Zahl zufällig stimmt. Wenn man dieses Problem vollständig elimieren will, muss man einen neuen Präprozessor einführen:
http://en.wikipedia.org/wiki/Hygienic_macro
-
µngbd schrieb:
Schlaue Idee. Leider kann es immer noch eine Variable geben, die v123 heisst, wenn die Zahl zufällig stimmt.
Wie hoch schätzt Du die Wahrscheinlichkeit ein, dass das zu Problemen führt?
-
logisch, ne? schrieb:
Wie hoch schätzt Du die Wahrscheinlichkeit ein, dass das zu Problemen führt?
Mit
gcc -Wshadow
? Null.
Sonst? EOD.
-
Ich kann's mir doch nicht verkneifen:
Shriram Krishnamurthi schrieb:
Many macro systems, such as that of C, are not hygienic. Programmers sometimes try to circumvent this by
using hideous identifier names, such as __macro_result_. This is not a solution!1. Not only is a it painful to have to program this way, small typos would greatly increase development
time, and the macro would be much harder to decipher when a programmer tries to modify or correct
it later.2. This solution is only as good as the programmer’s imagination; the problem still persists, lying in wait
for just the right (wrong!) identifier to be bound in the context of use. Indeed, while a programmer
may choose a sufficiently obscure name from the perspective of other programmers, not all source is
written by humans. A tool generating C code (such as a Scheme-to-C compiler) may happen to use
exactly this naming convention.3. This name is only obscure “upto one level”. If the macro definition is recursive, then recursive in-
stances of the macro may interfere with one another.
4. If you use this macro to debug the source that contains the macro (e.g., compiling the C compiler
using itself), then your carefully-chosen “obscure” name is now guaranteed to clash!
-
Dein Programm war ja mal totaler Unsinn. Hast du überhaupt eine Ahnung, was * und & bedeuten?
int tausch(char *a, char *b) { char *d; d=b; b=a; a=d; return 0; } int main(int argc, char *argv[]) { char * a="ABC"; char * b="DEF"; printf("1:(a|b): (%s|%s)\n",a,b); tausch(a,b); printf("2:(a|b): (%s|%s)\n",a,b); return 0; }
P.S.: Man gibt 0 zurück, falls alles in Ordnung ist.
-
earli schrieb:
Dein Programm war ja mal totaler Unsinn. Hast du überhaupt eine Ahnung, was * und & bedeuten?
int tausch(char *a, char *b) { char *d; d=b; b=a; a=d; return 0; } int main(int argc, char *argv[]) { char * a="ABC"; char * b="DEF"; printf("1:(a|b): (%s|%s)\n",a,b); tausch(a,b); printf("2:(a|b): (%s|%s)\n",a,b); return 0; }
P.S.: Man gibt 0 zurück, falls alles in Ordnung ist.
na sauber
-
das hat schon so gestimmt, nur inline und void als rückgabe wär evtl. die lösung
-
earli schrieb:
Dein Programm war ja mal totaler Unsinn. Hast du überhaupt eine Ahnung, was * und & bedeuten?
Du offensichtlich noch weniger.
earli schrieb:
Man gibt 0 zurück, falls alles in Ordnung ist.
Weil 0 für "false" steht. Mannmannmann....
-
logisch, ne? schrieb:
earli schrieb:
Dein Programm war ja mal totaler Unsinn. Hast du überhaupt eine Ahnung, was * und & bedeuten?
Du offensichtlich noch weniger.
earli schrieb:
Man gibt 0 zurück, falls alles in Ordnung ist.
Weil 0 für "false" steht. Mannmannmann....
Nö, 0 steht in der shell für true.
-
und ist das glas jetzt halb voll oder halb leer
-
volkard schrieb:
Nö, 0 steht in der shell für true.
In "der" Shell? Trotzdem kein Grund die Tauschfunktion eine 0 zurückgeben zu lassen wenn es geklappt hat.
if (!tausch(...)) /* Hat geklappt, hat nicht geklappt, hat ... ??? */ { ... }
-
eris schrieb:
Dein Programm war ja mal totaler Unsinn. Hast du überhaupt eine Ahnung, was * und & bedeuten?
Warum so unfreundlich? Finde ich seltsam, einmal abgesehen davon, dass du dich damit selbst ins lächerliche ziehst, sobald du einen Flüchtigkeitsfehler machst. Und das ist nur allzu menschlich.
-
earli schrieb:
Dein Programm war ja mal totaler Unsinn. Hast du überhaupt eine Ahnung, was * und & bedeuten?
int tausch(char *a, char *b) { char *d; d=b; b=a; a=d; return 0; }
deins ist auch nicht gerade besser. In anderen Worten: Dein Programm *ist* ja mal totaler Unsinn. Hast du überhaupt eine Ahnung, was * und & bedeuten?
logisch, ne? schrieb:
volkard schrieb:
Nö, 0 steht in der shell für true.
In "der" Shell? Trotzdem kein Grund die Tauschfunktion eine 0 zurückgeben zu lassen wenn es geklappt hat.
if (!tausch(...)) /* Hat geklappt, hat nicht geklappt, hat ... ??? */ { ... }
wieso nicht? Wenn man sich an einer Konvention hält, ist das OK. POSIX hat viele Funktionen, die im Erfolgfall 0 zurückliefern. Das Ergebnis != 0 ist somit gleich dem Fehlercode. Ich finde das ganz praktisch.
-
logisch, ne? schrieb:
volkard schrieb:
Nö, 0 steht in der shell für true.
In "der" Shell? Trotzdem kein Grund die Tauschfunktion eine 0 zurückgeben zu lassen wenn es geklappt hat.
if (!tausch(...)) /* Hat geklappt, hat nicht geklappt, hat ... ??? */ { ... }
wieso sollte die überhaupt was zurück geben? die kann doch keinen fehler machen
-
wieso nimmst du nicht wieder deinen alten noob nick. dieser ist doch kacke
:p
-
wie konntest du meine tarnung aufdecken
muß an meinem schlechten deutsch liegen :p