C-Makros und Verwendung von Argumenten in Klammern

Lesezeit: 4 Minuten

Benutzer-Avatar
rubixibuc

Beispiel

#define Echo(a)  a
#define Echo(a) (a)

Mir ist klar, dass es hier wahrscheinlich keinen signifikanten Unterschied gibt, aber warum sollten Sie jemals die einbeziehen wollen a in Klammern innerhalb des Makrokörpers? Wie verändert es sich?

  • mögliches Duplikat von Die Notwendigkeit von Klammern in Makros in C

    – Paläc

    29. April 2015 um 8:35 Uhr

  • Die Frage Die Notwendigkeit von Klammern in Makros in C ist ein Duplikat davon und nicht umgekehrt und wird nun als solche geschlossen.

    – Jonathan Leffler

    10. Februar 2018 um 20:58 Uhr

  • Verwandte Fragen: Können wir die Klammern um Argumente in C-Makrodefinitionen entfernen? und Wann können die Klammern um Argumente in Makros weggelassen werden?

    – Jonathan Leffler

    10. Februar 2018 um 21:01 Uhr

Benutzer-Avatar
Cnicutar

Angenommen, Sie haben

#define mul(x, y)  x * y

Was passiert, wenn ich sage:

mul(a + 5, 6); /* a + 5 * 6 */

Wenn ich jetzt das Makro etwas verändere:

#define mul(x, y)  ((x) * (y))
mul(a + 5, 6); /* ((a + 5) * (6)) */

Denken Sie daran, die Argumente werden nicht ausgewertet oder so, es wird nur eine Textersetzung durchgeführt.

BEARBEITEN

Eine Erklärung dazu, wie das gesamte Makro in Klammern steht, finden Sie unter die Verbindung Gepostet von Nate CK.

  • Danke, ich war nur verwirrt, weil in dem Buch, das ich verwende, die Art und Weise, wie sie sie verwendet haben, überflüssig erschien. Sie hatten so etwas wie dieses foo(bar) (bar)->etwas, wären sie hier notwendig?

    – rubixibuc

    25. August 2011 um 7:30 Uhr


  • Du meinst wahrscheinlich foo(bar) (bar)->somethingund ja, sie sind notwendig.

    – Cnicutar

    25. August 2011 um 7:31 Uhr

  • Sry zu fragen, aber wie ist es dort notwendig?

    – rubixibuc

    25. August 2011 um 7:33 Uhr

  • Ich habe die gesamte verlinkte Seite gelesen und verstehe immer noch nicht, wie das falsch geparst werden könnte

    – rubixibuc

    25. August 2011 um 7:34 Uhr


  • Angenommen, Sie haben ein Array von Strukturen, und das haben Sie aus irgendeinem Grund foo(bar+5). Das wäre völlig in Ordnung, wenn foo wäre eine Funktion, aber wenn es sich um ein Makro ohne die Klammer handelt, endet es als bar+5->something. Ähnlich wenn bar ist ein Zeiger auf einen Zeiger, und Sie tun es foo(*bar) was am Ende als *bar->something was sicherlich falsch ist, werden Sie wollen (*bar)->something

    – Nr

    25. August 2011 um 7:41 Uhr

Benutzer-Avatar
Michi

Nur fürs Protokoll, ich bin hier gelandet, wie man mathematische Fehler bei der Verwendung von Makros behebt, und ich werde versuchen, diese Antwort hier so zu erweitern, dass sie zu der anderen passt.

Sie fragen nach dem Unterschied zu:

#define Echo( a )  a
#define Echo( a ) ( a )

was in Ordnung ist, solange Sie das Makro selbst nicht verstehen (ich bin auch kein Experte 🙂 ).

Zunächst einmal wissen Sie (wahrscheinlich) bereits, dass es Operator Precedence gibt, also gibt es einen großen Unterschied zwischen diesen beiden Programmen:

1):

#include <stdio.h>
#define ADD( a , b ) a + b

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD (  2 + a ,  2 + b );
    printf( "%d", c );
    return 0;
}

Ausgabe:

19

und:

#include <stdio.h>
#define ADD( a , b ) ( a ) + ( b )

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( a , b );
    printf( "%d", c );
    return 0;
}

Ausgabe:

15

Lassen Sie uns nun voranstellen + mit *:

#define ADD( a, b ) a * b

Der Compiler behandelt a * b wie zum Beispiel a == 5 und b == 10 was tut 5 * 10.

Aber wenn du sagst:
ADD ( 2 + a * 5 + b )
Wie hier:

#include <stdio.h>
#define ADD( a , b ) ( a ) * ( b )

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( 2 + a , 5 + b );
    printf( "%d", c );
    return 0;
}

Du erhältst 105weil der Operator Vorrang beteiligt ist und behandelt

2 + b * 5 + a

wie

( 2 + 5 ) * ( 5 + 10 )

welches ist

( 7 ) * ( 15 ) == 105

Aber wenn du es tust:

#include <stdio.h>
#define ADD( a, b ) a * b

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( 2 + a , 5 + b );
    printf( "%d", c );
    return 0;
}

du erhältst 37 durch

 2 + 5 * 5 + 10

was bedeutet:

2 + ( 5 * 5 ) + 10

was bedeutet:

2 + 25 + 10

Kurze Antwort, es gibt einen großen Unterschied zwischen:

#define ADD( a , b ) a * b

und

#define ADD( a , b ) ( a ) * ( a )

  • Warum schreibst du auto vor Variablen? Es ist völlig überflüssig

    – Erich W

    10. Februar 2018 um 17:32 Uhr

  • @ErikW Bitte erklären Sie mir, was genau Sie bei der Verwendung falsch finden auto in diesen Beispielen?

    – Michi

    10. Februar 2018 um 17:43 Uhr

  • Sie müssen nie schreiben auto in C, da alle Variablen automatisch sind, wenn sie im Geltungsbereich deklariert werden (außer wenn sie als explizit deklariert sind static). Es ist nicht falsch, aber unnötig.

    – Erich W

    10. Februar 2018 um 21:18 Uhr


  • @ErikW Ich kann Ihre Frage nicht beantworten, solange Sie nicht der Meinung sind, dass die Verwendung von auto in C falsch ist.

    – Michi

    10. Februar 2018 um 22:04 Uhr

  • Wahrscheinlich wäre die gleiche Frage: Warum verwenden die Leute nicht return in main? Nur weil das seit 99 implizit ist?

    – Michi

    10. Februar 2018 um 22:17 Uhr

1298180cookie-checkC-Makros und Verwendung von Argumenten in Klammern

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy