当前位置:网站首页>Détails du prétraitement du langage C

Détails du prétraitement du langage C

2021-10-14 07:32:31 - Non.

Table des matières

Un.,Symboles prédéfinis

2.,#define

 1,#define Définir l'identificateur

2,#define Macro personnalisée

3,#define Règle de remplacement

 Trois,##Le rôle de

1,Concept

 2,Macro - paramètre avec effets secondaires

 3,Comparaison des macros et des fonctions

Trois,Convention de nommage

1,#undef

2,Le fichier contient


Un.,Symboles prédéfinis

__FILE__      //Fichier source à compiler
__LINE__     //Numéro de ligne actuel du fichier
__DATE__    //Date à laquelle le fichier a été compilé
__TIME__    //Temps de compilation du fichier
__STDC__    //Si le compilateur suitANSI C,Sa valeur est1,Sinon, non défini
 int main()
{
	printf("%s\n", __FILE__);
	printf("%d\n", __LINE__);
	printf("%s\n", __DATE__);
	printf("%s\n", __TIME__);
	//printf("%d\n", __STDC__);//Parce queVSNon pris en chargeANSI C,En fait...__STDC__Non défini
	//gcc Oui.
	//gccC'est exact.C Le support de la grammaire linguistique est très bon 

	return 0;
}

 Ces symboles prédéfinis sont intégrés dans la langue,Voici quelques exemples:

 int main()
 {
	 printf("file:%s line:%d\n", __FILE__, __LINE__);
	 return 0;
 }

2.,#define

 1,#define Définir l'identificateur

#define name stuff
#define MAX 100
#define reg register    //Pour registerCe mot - clé,Créer un nom court
#define STR "HEHE"
int main()
{
	int a = 3;
	int b = 20;
	if (a == 4)
		b = MAX;
	else
		b = -a;
	register int num = 100;
	reg int num2 = 200;

	int m = MAX;
	printf("%d\n", MAX);
	printf("%d\n", m);
	printf("%s\n", STR);

	return 0;
}

 IndefineLors de la définition d'un identificateur,Voulez - vous ajouter à la fin ; ?

#define MAX 1000;
int main()
{
	int x = 1;
	int max;
	if (x==1)
	{
		max = MAX;// Remplacer ici par  MAX 1000;;Erreur de syntaxe
	}
	else
	{
		max = 0;
	}
	printf("%d", max);
	return 0;
}

2,#define Macro personnalisée

#define Le mécanisme comprend une disposition,Autoriser le remplacement des paramètres dans le texte,Cette mise en œuvre est souvent appelée macro(macro)Ou définir une macro(define macro).

Voici comment macro affirme :

#define name( parament-list ) stuff Dont: parament-list Est une liste de symboles séparés par des virgules,Ils peuvent apparaître dans stuffMoyenne.

Attention!: La parenthèse gauche de la liste des paramètres doit êtrenameÀ côté.. S'il y a un vide entre les deux,La liste des paramètres sera interprétée commestuffUne partie de Points.

#define SQUARE( x ) x * x

Cette macro reçoit un paramètre x=5.

SQUARE( 5 );

Comment le programme s'exprime - t - il ,Comme suit

5 * 5
int a = 5;
printf("%d\n" ,SQUARE( a + 1) );

Regardez le code ci - dessus , Que pensez - vous du résultat ?

En remplaçant le texte ,ParamètresxRemplacé para + 1, Donc cette déclaration devient en fait : printf ("%d\n",a + 1 * a + 1 );

Ajouter deux parenthèses à la définition de macro , Ce problème est facilement résolu :

#define SQUARE(x) (x) * (x)

De cette façon, le prétraitement produit l'effet désiré :

printf ("%d\n",(a + 1) * (a + 1) );
#define SQUARE(X) ((X)*(X))

int main()
{
	int a = 5;
	int ret = SQUARE(a+5);
	//int ret = a + 5 * a + 5;
	//int ret = ((a) * (a));
	printf("%d\n", ret);

	return 0;
}

  Il y a aussi une définition de macro :

#define DOUBLE(x) (x) + (x)

Nous avons utilisé des parenthèses dans la définition , Pour éviter les problèmes précédents , Mais cette macro peut avoir de nouvelles erreurs .

int a = 5; 
printf("%d\n" ,10 * DOUBLE(a)); 

C'est comme imprimer 100, Mais en fait, c'est imprimé 55. Après avoir trouvé le remplacement :

printf ("%d\n",10 * (5) + (5));

Cette question, La solution est d'ajouter une paire de parenthèses autour de l'expression de définition de macro .

#define DOUBLE(x) ( ( x ) + ( x ) )
#define DOUBLE(X) ((X)+(X))

int main()
{
	int ret = 10 * DOUBLE(2);
	//int ret = 10 * 2 + 2;

	printf("%d\n", ret);

	return 0;
}

 Conseils: Par conséquent, les macrodéfinitions utilisées pour évaluer les expressions numériques doivent être parenthèses de cette façon , Évitez d'utiliser des macros en raison d'opérateurs dans les paramètres ou Interactions imprévisibles entre opérateurs voisins .

3,#define Règle de remplacement

Lors de l'appel d'une macro,Vérifiez d'abord les paramètres,Voir s'il contient des informations#defineSymboles définis.Si oui,Ils sont remplacés en premier.

Le texte de remplacement est ensuite inséré à l'emplacement du texte original dans le programme.Pour macros,Les noms des paramètres sont remplacés par leurs valeurs.

Enfin,Numériser à nouveau le fichier de résultats,Voir s'il contient des éléments#defineSymboles définis.Si oui,Répétez le processus ci - dessus..

Attention!:

Paramètres macro et#define D'autres peuvent apparaître dans la définition#defineVariables définies.Mais pour les macros,La récursion ne peut pas se produire.

Lorsque le préprocesseur recherche#defineLorsque le symbole est défini,Le contenu d'une constante de chaîne n'est pas recherché.

#define PRINT(n) printf("the value of "#n" is %d\n", n)

int main()
{
	int a = 10;
	PRINT(a);
	int b = 20;
	PRINT(b);
	return 0;
}

 Avec#defineChaîne de connexion

#define PRINT(FORMAT, VALUE)
printf("the value is "FORMAT"\n", VALUE);
PRINT("%d", 10);
#define PRINT(n) printf("the value of "#n" is %d\n", n)

int main()
{
	int a = 10;
	printf("the value of a is %d\n", a);
	int b = 20;
	printf("the value of b is %d\n", b);
	printf("hello world\n");
	printf("hello ""world\n");
	return 0;
}

 Trois,##Le rôle de

1,Concept

##Il est possible de combiner les symboles situés de chaque côté en un seul symbole. Il permet aux macrodéfinitions de créer des identificateurs à partir de fragments de texte séparés.

#define ADD_TO_SUM(num, value) 
sum##num += value; 

ADD_TO_SUM(5, 10);//La fonction est::Voilà.sum5Ajouter10.
#define CAT(X,Y) X##Y

int main()
{
	int class103 = 100;
	printf("%d\n", CAT(class, 103));
	printf("%d\n", CAT(1, 2));
	return 0;
}

 2,Macro - paramètre avec effets secondaires

Lorsque le paramètre macro apparaît plus d'une fois dans la définition de macro,Si le paramètre a des effets secondaires,Alors vous pourriez être en danger en utilisant cette macro,Guide Conséquences imprévisibles .L'effet secondaire est l'effet permanent qui se produit lorsque l'expression est évaluée. Par exemple:

x+1;//Sans effets secondaires
x++;//Avec effets secondaires

MAX Les macros peuvent démontrer les problèmes causés par les paramètres qui ont des effets secondaires .

int main()
{
	int a = 10;
	int b = a + 1;//bCe qu'on a, c'est11,aSans changement
	int b = ++a;//bCe qu'on a, c'est11,MaisaÇa a changé., Cette expression a des effets secondaires 
	return 0;
}
int Max(int x, int y)
{
	return x > y ? x : y;
}

int main()
{
	int a = 5;
	int b = 8;
	
	//int m = MAX(a++, b++);
	//int m = ((a++) > (b++) ? (a++) : (b++));
	// Les paramètres de la fonction sont calculés et transmis à 
	int m = Max(a++, b++);

	printf("m=%d\n", m);//8
	printf("a=%d\n", a);//6
	printf("b=%d\n", b);//9


	return 0;
}

//Mise en œuvre de macros - 1
#define MAX(X,Y) ((X)>(Y)?(X):(Y))
int Max(int x, int y)
{
	return x > y ? x : y;
}

int main()
{
	int a = 5;
	int b = 8;
	// Les paramètres d'une macro ne sont pas calculés pour être directement remplacés 
	// Remplacer et entrer dans l'opération 

	int m = Max(a++, b++);

	printf("m=%d\n", m);//8
	printf("a=%d\n", a);//6
	printf("b=%d\n", b);//9

	return 0;

 3,Comparaison des macros et des fonctions

Les macros sont généralement utilisées pour effectuer des opérations simples.Comme trouver le plus grand des deux nombres.

#define MAX(a, b) ((a)>(b)?(a):(b)) 

Le code utilisé pour invoquer une fonction et pour la renvoyer peut prendre plus de temps qu'il ne faut pour effectuer ce petit calcul.Alors...Les macros surpassent les fonctions en termes de taille et de vitesse du programme.

Plus important encore, les arguments de la fonction doivent être déclarés comme un type spécifique.Par conséquent, les fonctions ne peuvent être utilisées que sur des expressions de type approprié.Comment cette macro peut - elle être différente? Pour le façonnage、Forme longue、Les points flottants, etc., peuvent être utilisés pour>Types à comparer.Les macros sont indépendantes du type.

Les inconvénients des macros

Chaque fois que vous utilisez une macro,Un code macro - défini sera inséré dans le programme.Sauf si la macro est plus courte,Sinon, la longueur du programme peut être considérablement augmentée..

Les macros ne peuvent pas être déboguées.

Macro indépendante du type,Ce n'est pas assez précis..

Les macros peuvent causer des problèmes avec la priorité de l'opérateur,Le processus est sujet aux erreurs.

Genre Sexe #defineMacro personnalisée Fonctions
Génération Code Long Degré Chaque fois qu'il est utilisé,Le macro - Code est inséré dans le programme. Sauf pour les très petites macros Au - delà,La durée du programme augmentera considérablement Le Code de fonction n'apparaît qu'en un seul endroit;Chaque fois Avec cette fonction , Appelez le même endroit Un code
Oui. D'accord Vitesse Degré Plus vite. Il y a des frais généraux supplémentaires pour les appels et les retours de fonctions, Donc C'est un peu plus lent.
Putain! Faire Rune Oui. D'abord. Niveau Le paramètre macro est évalué dans le contexte de toutes les expressions environnantes, Sauf si plus Parenthèses supérieures , Sinon, la priorité de l'opérateur adjacent peut produire un post inattendu Résultats,Il est donc conseillé aux macros d'écrire entre parenthèses Le paramètre de fonction n'est évalué qu'au moment de l'appel de fonction Une fois,Sa valeur résultante est passée à la fonction.Expression Les résultats de l'évaluation sont plus prévisibles .
Avec Oui. Deputy Faire Avec De Voir Nombre Les paramètres peuvent être remplacés à plusieurs endroits dans le macrocorps, Donc le paramètre avec les effets secondaires L'évaluation des nombres peut produire des résultats inattendus . Le paramètre de fonction n'est évalué qu'une seule fois lors du passage du paramètre, Les résultats sont plus faciles à contrôler.
Voir Nombre Catégorie Type Les paramètres de la macro sont indépendants du type,Tant que l'opération sur le paramètre est légale, C'est juste Pour être utilisé avec n'importe quel type de paramètre . Les arguments de la fonction sont liés au type, Si tu veux Les types de nombres sont différents ,Une fonction différente est nécessaire, Même si les tâches qu'ils accomplissent sont différentes
Tune Essayez. Les macros ne sont pas faciles à déboguer Les fonctions peuvent être déboguées par instruction
Passe. Retour à Les macros ne peuvent pas être récursives Les fonctions sont récursives

Trois,Convention de nommage

En général, les macros d'une fonction utilisent une syntaxe très similaire.Donc la langue elle - même ne peut pas nous aider à distinguer les deux. Une de nos habitudes habituelles est:

Majuscule tous les noms de macro Le nom de la fonction ne doit pas être entièrement majuscule

1,#undef

Cette instruction supprime une définition de macro.

#undef NAME 
//Si un nom existant doit être redéfini,Son ancien nom doit d'abord être supprimé.

Définition de la ligne de commande

BeaucoupC Le compilateur de,Autoriser la définition de symboles sur la ligne de commande.Pour démarrer le processus de compilation. Par exemple: Quand on a besoin de Lorsque vous compilez différentes versions d'un programme différent ,Cette fonctionnalité est utile.(Supposons qu'un tableau d'une certaine longueur soit déclaré dans un programme,Si La mémoire de la machine est limitée ,Il nous faut un petit tableau,Mais l'autre machine a une mémoire en majuscules,Nous avons besoin d'un tableau capable de capitaliser.)

#define	MAX 100

int main()
{
	int m = MAX;
    #undef MAX
	int n = MAX;//err
	return 0;
}
#define M 500

int main()
{
#if M==100
	printf("haha\n");
#elif M==200
	printf("hehe\n");
#else
	printf("heihei\n");
#endif

	return 0;
}

2,Le fichier contient

Nous le savons déjà., #include La directive permet de compiler un autre fichier.C'est comme si c'était #include La directive est la même.. Cette substitution est simple: Le préprocesseur supprime d'abord cette instruction,Et remplacer par le contenu du fichier contenant. Un tel fichier source est inclus10Une fois,Alors... Effectivement compilé 10Une fois.

Comment les fichiers d'en - tête sont contenus:

#include "filename" 

 VSChemin vers le fichier d'en - tête standard pour l'environnement:

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include

Le fichier de la bibliothèque contient

#include <filename.h>

版权声明
本文为[- Non.]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/10/20211013211336193i.html

随机推荐