C/Compilatore e precompilatore/Direttive: differenze tra le versioni

Wikibooks, manuali e libri di testo liberi.
Contenuto cancellato Contenuto aggiunto
BimBot (discussione | contributi)
m robot Aggiungo: pl:C/Preprocesor
Pietrodn (discussione | contributi)
+sintassi colorata
Riga 12: Riga 12:
==={{IndexItem|direttive #define}}<tt>#define</tt>===
==={{IndexItem|direttive #define}}<tt>#define</tt>===
La direttiva <tt>#define</tt> serve per definire {{IndexItem|macro}}macro. Sintassi:
La direttiva <tt>#define</tt> serve per definire {{IndexItem|macro}}macro. Sintassi:
<source lang="c">
#define nomemacro testomacro
#define nomemacro testomacro
</source>


Il testo può essere una {{IndexItem|costanti}}costante o un'{{IndexItem|espressioni}}espressione, anche parametrizzata:
Il testo può essere una {{IndexItem|costanti}}costante o un'{{IndexItem|espressioni}}espressione, anche parametrizzata:
<source lang="c">
<pre>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
Riga 28: Riga 30:
return 0;
return 0;
}
}
</pre>
</source>
Abbiamo trattato l'{{IndexItem|operatore ?}}operatore ? [[Linguaggio_C/Blocchi_e_funzioni/Blocchi_if_e_switch#L.27operatore_.3F|qui]].
Abbiamo trattato l'{{IndexItem|operatore ?}}operatore ? [[Linguaggio_C/Blocchi_e_funzioni/Blocchi_if_e_switch#L.27operatore_.3F|qui]].


Riga 40: Riga 42:


Esempio:
Esempio:
<source lang="c">
<pre>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
Riga 67: Riga 69:
return 0;
return 0;
}
}
</pre>
</source>


Tale codice, una volta elaborato dal preprocessore, è equivalente al seguente:
Tale codice, una volta elaborato dal preprocessore, è equivalente al seguente:
<source lang="c">
<pre>
/*... trascrizione completa dei file stdio.h e stdlib.h...*/
/*... trascrizione completa dei file stdio.h e stdlib.h...*/


Riga 79: Riga 81:
return 0;
return 0;
}
}
</pre>
</source>


Si noti che il preprocessore sostituisce ogni occorrenza delle macro con il loro testo equivalente.
Si noti che il preprocessore sostituisce ogni occorrenza delle macro con il loro testo equivalente.
Riga 86: Riga 88:
La direttiva <tt>#include</tt> è molto importante: permette di includere un file C in un altro. La sua sintassi è la seguente:
La direttiva <tt>#include</tt> è molto importante: permette di includere un file C in un altro. La sua sintassi è la seguente:


<source lang="c">
#include <file.h>
#include <file.h>
#include "file.h"
#include "file.h"
</source>


Qual è la differenza fra parentesi angolari e virgolette? Dipende dal compilatore, ma solitamente con le parentesi angolari il {{IndexItem|linker}}linker cerca nelle directory della libreria standard, mentre con le virgolette si cerca il file prima all'interno della directory corrente e poi all'interno delle directory della libreria standard.
Qual è la differenza fra parentesi angolari e virgolette? Dipende dal compilatore, ma solitamente con le parentesi angolari il {{IndexItem|linker}}linker cerca nelle directory della libreria standard, mentre con le virgolette si cerca il file prima all'interno della directory corrente e poi all'interno delle directory della libreria standard.
Riga 98: Riga 102:
La sintassi è:
La sintassi è:


<source lang="c">
#line numerolinea "nomefile"
#line numerolinea "nomefile"


Esempio:
Esempio:
<source lang="c">
<pre>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
Riga 112: Riga 117:
return 0;
return 0;
}
}
</pre>
</source>


Il file è opzionale.
Il file è opzionale.
Riga 122: Riga 127:
La direttiva <tt>#undef</tt> serve per cancellare delle macro definite in precedenza con <tt>#define</tt>. Sintassi:
La direttiva <tt>#undef</tt> serve per cancellare delle macro definite in precedenza con <tt>#define</tt>. Sintassi:


<source lang="c">
#undef macro
#undef macro
</source>


Esempio:
Esempio:
<source lang="c">
<pre>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
Riga 136: Riga 143:
return 0;
return 0;
}
}
</pre>
</source>


==Operatori==
==Operatori==
Riga 147: Riga 154:
Esempio:
Esempio:


<source lang="c">
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
Riga 156: Riga 164:
return 0;
return 0;
}
}
</source>


===L'operatore {{IndexItem|operatore ##}}<tt>##</tt>===
===L'operatore {{IndexItem|operatore ##}}<tt>##</tt>===
Riga 161: Riga 170:
Questo operatore si chiama ''operatore di concatenamento''. Esempio:
Questo operatore si chiama ''operatore di concatenamento''. Esempio:


<source lang="c">
<pre>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
Riga 172: Riga 181:
return 0;
return 0;
}
}
</pre>
</source>


Questo programma stamperà il numero 10.
Questo programma stamperà il numero 10.

Versione delle 17:44, 27 mag 2007

Template:Linguaggio C Il precompilatore può eseguire diverse istruzioni.

Le direttive

Le direttive sono delle istruzioni al precompilatore e dipendono dal compilatore stesso, per cui è consigliabile consultarne la documentazione.

Le direttive non finiscono con il punto e virgola ma con la fin di riga.

Ecco le direttive:

#define

La direttiva #define serve per definire macro. Sintassi:

 #define nomemacro testomacro

Il testo può essere una costante o un'espressione, anche parametrizzata:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
#define NUM 10
#define EXPR(a) (a)==6 ? 6 : 0
	
	printf("%d\n", NUM);
	printf("%d\n", EXPR(7));
return 0;
}

Abbiamo trattato l'operatore ? qui.

#if, #else, #elif ed #endif

Queste direttive servono per la compilazione condizionale. Il loro uso è del tutto analogo a quello dell'istruzione if, ma con una sostanziale differenza: mentre in una normale istruzione if la condizione viene valutata a tempo di esecuzione per decidere quale gruppo di istruzioni eseguire, la direttiva #if seleziona a tempo di compilazione quale gruppo di istruzioni debba essere compilato, mentre le istruzioni scartate vengono completamente rimosse e, ai fini del codice eseguibile prodotto, è come non fossero esistite.

Come conseguenza immediata, le espressioni lecite in una direttiva #if sono solo ed esclusivamente quelle valutabili interamente a tempo di compilazione.

Una forma particolare di direttiva #if è la #ifdef e la sua corrispondente negata #ifndef, che restituiscono un valore di verità rispettivamente vero e falso se la macro fornita come parametro è stata precedentemente definita.

Esempio:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
#define NUM 10
#define EXPR(a) (a)==6 ? 6 : 0

#ifdef NUM	// vera: NUM è stato precedentemente definito
#if NUM==10	// vera
	printf("NUM è uguale a 10.\n");
#if EXPR(6)	// vera: per un valore pari a 6 del parametro, l'espressione restituisce 6
		printf("EXPR ha dato un risultato! %d\n", EXPR(6));
#else
		printf("EXPR non ha dato alcun risultato!\n");
#endif
#elif NUM<10	// falsa
		printf("NUM è minore di 10: %d\n", NUM);
#else
		printf("NUM è maggiore di 10: %d\n", NUM);
#endif
#else
		printf("NUM non è definito.\n");
#endif
return 0;
}

Tale codice, una volta elaborato dal preprocessore, è equivalente al seguente:

/*... trascrizione completa dei file stdio.h e stdlib.h...*/

int main(void)
{
	printf("NUM è uguale a 10.\n");
		printf("EXPR ha dato un risultato! %d\n", (6)==6 ? 6 : 0);
return 0;
}

Si noti che il preprocessore sostituisce ogni occorrenza delle macro con il loro testo equivalente.

#include

La direttiva #include è molto importante: permette di includere un file C in un altro. La sua sintassi è la seguente:

 #include <file.h>
 #include "file.h"

Qual è la differenza fra parentesi angolari e virgolette? Dipende dal compilatore, ma solitamente con le parentesi angolari il linker cerca nelle directory della libreria standard, mentre con le virgolette si cerca il file prima all'interno della directory corrente e poi all'interno delle directory della libreria standard.

#line

La direttiva #line permette di alterare il contenuto delle macro __LINE__ e __FILE__. Essa non salta ad un altro punto del programma; modifica semplicemente queste macro.

La sintassi è:

 #line numerolinea "nomefile"

Esempio:
<source lang="c">
#include <stdio.h>
#include <stdlib.h>

#line 70 "prova.c"

int main(void) //linea 71
{ //Linea 72
	printf("Linea: %d; File: %s\n", __LINE__, __FILE__); //Linea 73
 return 0;
}

Il file è opzionale.

#pragma

La direttiva #pragma serve per inviare particolari istruzioni al compilatore. Le opzioni disponibili variano da compilatore a compilatore, per cui è consigliabile consultarne la documentazione.

#undef

La direttiva #undef serve per cancellare delle macro definite in precedenza con #define. Sintassi:

 #undef macro

Esempio:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
#define NUM 10
	printf("NUM: %d\n", NUM);
#undef NUM
return 0;
}

Operatori

Il preprocessore accetta anche degli speciali operatori:

L'operatore #

Questo operatore serve per trasformare una sequenza di caratteri in stringa all'interno di una macro.

Esempio:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
#define str(s) # s
	printf(str(Il C mi piace molto.));
 return 0;
}

L'operatore ##

Questo operatore si chiama operatore di concatenamento. Esempio:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
#define cat(x,y) x ## y
	int cd=10;
	printf("%d\n", cat(c,d));
 return 0;
}

Questo programma stamperà il numero 10.

L'operatore defined

Le macro

Il linguaggio C definisce anche delle macro:

__DATE__

La macro __DATE__ contiene la data della compilazione nel formato mese/giorno/anno.

__FILE__

La macro __FILE__ contiene il nome del file correntemente in compilazione. Può essere modificata con la direttiva #line.

__LINE__

La macro __LINE__ contiene il numero della linea correntemente in compilazione. Può essere modificata con la direttiva #line.

__TIME__

La macro __TIME__ contiene l'ora della compilazione nel formato ore:minuti:secondi.

__STDC__

Il contenuto della macro __STDC__ varia da compilatore a compilatore. Solitamente, se essa è definita, il compilatore accetterà soltanto codice C standard.