Muuttujamakro - C-esiprosessorin kyky ilmoittaa tuen eri määrälle argumentteja käyttämällä erityistä makroa .
Muuttuja -argumenttimakrot otettiin käyttöön C-ohjelmointikielistandardin ISO /IEC 9899:1999 ( C99 ) -versiossa vuonna 1999. Tällaisia makroja otettiin käyttöön myös C++-ohjelmointikielen ISO/IEC 14882:2011 ( C++11 ) -versiossa. standardi vuonna 2011 [1] .
Ilmoituksen syntaksi on samanlainen kuin variadic-funktion syntaksi : poistoa " ... " käytetään osoittamaan, että nolla tai useampi argumentti voidaan välittää. Kun makroa laajennetaan, jokainen makron korvausluettelon erikoistunnisteen __VA_ARGS__ kutsu korvataan välitetyillä argumenteilla.
Muodollisen parametriluettelon yksittäisiä argumentteja ei käsitellä arvon tai niiden välitystavan perusteella.
Gcc:ssä muodollisten makroparametrien luettelo voi sisältää joko määritettyjä argumentteja tai vaihtoehtoisesti välitettyjä argumentteja (katso esimerkki).
GNU Compiler Collection versiosta 3.0 lähtien, C++ Builder 2006 ja Visual Studio 2005 [1] tukevat muuttuja-argumenttimakroja käännettäessä sekä C- että C++-koodia . Lisäksi GCC tukee muuttujamakroja käännettäessä Objective-C- koodia .
Jos tarvitset printf - kuten dprintf () -funktion , joka ottaa argumentiksi tiedostonimen ja rivinumeron, josta sitä kutsutaan, voit käyttää seuraavaa makroa:
void realdprintf ( char const * tiedosto , int rivi , char const * fmt , ...); #define dprintf(...) realdprintf(__FILE__, __LINE__, __VA_ARGS__)dprintf() voidaan kutsua seuraavasti:
dprintf ( "Hei maailma" );joka on pehmustettu:
realdprintf ( __FILE__ , __LINE__ , "Hei, maailma" );tai:
dprintf ( "%d + %d =%d" , 2 , 2 , 5 );joka on pehmustettu:
realdprintf ( __TIEDOSTO__ , __LINE__ , "%d + %d =%d" , 2 , 2 , 5 );Epätäydellinen esimerkki ei kuvasta mahdollisuuksia, lisään:
#define CALL( _obj, _mtd, _specifiedArg1,_specifiedArg2, ... ) _obj->_mtd(_specifiedArg2,_specifiedArg1, __VA_ARGS__)siten on mahdollista manipuloida osaa ilmoitetuista argumenteista, esimerkissä argumentit vaihdetaan.
Joissakin tapauksissa tavallinen makrokutsu voi toimia vaihtoehtona vaihteleville makroille. Esimerkiksi seuraavaa koodia voidaan käyttää virheenkorjaukseen :
#ifdef TRACING # määritä TRACE(_p) printf _p #else #define TRACE(_p) #endifJos TRACING -makro määritellään käännöshetkellä, TRACE -makron kutsuminen vastaa printf -funktion kutsumista :
TRACE (( "Käynnissä oleva rivi %d \n " , __LINE__ ));Jos TRACING -makroa ei ole määritetty, viestiä ei tulosteta ohjelman ollessa käynnissä. Huomaa, että tämän makron kutsuparametrit on suljettava kaksoissulkeissa.
Joissakin muissa tapauksissa voit käyttää variadic-makrojen sijasta C/C++-kielten stdargs-toimintoa ja kutsua vprintf-funktiolle .
Toinen esimerkki:
#if määritelty ( DEBUG_MCU ) #määrittää TRACE( args ... ) printf( args ) #else # määrittää TRACE( args ... ) #endif