C language - preprocessing, the difference between macro definition and function with parameters

preprocessing

1. Basic introduction

(1) Before using the library function, you should use #include to introduce the corresponding header file. This command starting with # is called a preprocessing command .

(2) The process of simply processing the source file before compiling is called preprocessing (that is, preprocessing, advance processing)

(3) Preprocessing is mainly to process commands beginning with #, such as #include <stdio.h>, etc. Preprocessing commands should be placed outside all functions, and generally placed in front of the source file

(4) Preprocessing is an important function of C language, which is completed by the preprocessing program . When compiling a source file, the system will automatically call the preprocessing program to process the preprocessing part of the source program , and automatically enter the compilation of the source program after processing

(5) C language provides a variety of preprocessing functions, such as macro definition, file inclusion, conditional compilation, etc. Reasonable use of them will make the written program easy to read, modify, transplant and debug, and is also conducive to modular programming design


2. A small case, quick start

Develop a C language program, let it pause for 5 seconds and then output the content "helllo, Genrany!~", and require cross-platform, can run under Windows and Linux, how to deal with it?

hint:

(1) The prototype of the pause function under the Windows platform is void Sleep(DWORD dwMilliseconds), and the unit of the parameter is "milliseconds", which is located in the <windows.h> header file.

(2) The prototype of the suspend function under the Linux platform is unsigned int sleep (unsigned int seconds), and the unit of the parameter is "seconds", which is located in the <unistd.h> header file

(3) #if, #elif, #endif are preprocessing commands, they are all executed by the preprocessing program before compiling


#include <stdio.h>
#if _WIN32  //如果是windows平台,就执行#include <windows.h>
#include <windows.h>
#elif __linux__    //否则判断是不是linux,如果是linux就引入
#include <unistd.h>
#endif
int main() {
    
    
	//不同的平台下调用不同的函数
	#if _WIN32 //识别windows平台
	Sleep(5000);//毫秒
	#elif __linux__ //识别linux平台
	sleep(5);//秒
	#endif
	puts("hello, Genrany~");
	getchar();
	return 0; 
}

macro definition

1. Basic introduction

#define is called a macro definition command, which is also a kind of C language preprocessing command. The so-called macro definition is to use an identifier to represent a string . If the identifier appears in the following code, it will be replaced with the specified string.

#include <stdio.h>
//宏定义 ,宏名 M ,对应的字符串(n*n+3*n)
//注意:如果宏对应的字符串有(),那么就不能省略
#define M (n*n+3*n)
int main(){
    
    
	int sum ,n;
	printf("input a number");
	scanf("%d",&n);
	sum = 3*M + 4*M + 5*M;
	printf("sum=%d\n",sum);
	getchar();
	getchar();
	return 0;
}

image-20221026202132129

2. Precautions and details

(1) The macro definition uses the macro name to represent a string, and replaces the macro name with the string when the macro is expanded. This is just a simple replacement. The string can contain any character, it can be a constant, expression, if statement, function, etc. The preprocessor does not check it. If there is an error, it can only be found when compiling the source program that has been expanded by the macro .

(2) The macro definition is not a statement or a statement, and there is no need to add a semicolon at the end of the line. If a semicolon is added, even the semicolon will be replaced together

(3) The macro definition must be written outside the function, and its scope is from the macro definition command to the end of the source program. To end its scope use the #undef command

#define PI 3.14159
int main(){
printf("PI=%f", PI);
return 0;
}
#undef PI //取消宏定义
void func(){
	printf("PI=%f", PI);//错误,这里不能使用到PI了
}

(4) If the macro name in the code is surrounded by quotation marks, the preprocessor will not replace it with a macro

image-20221026202933663

(5) The macro definition allows nesting. The defined macro name can be used in the string of the macro definition, and it will be replaced layer by layer by the preprocessor when the macro is expanded.

(6) It is customary to use capital letters for macro names to distinguish them from variables. but lowercase letters are also allowed

(7) Macro definitions can be used to represent data types, making writing convenient

image-20221026203255149

(8) The difference between the macro definition representing the data type and the data specifier defined by typedef: the macro definition is just a simple string replacement **, which is processed by the preprocessor; while the typedef is processed by the compiler during the compilation phase, it does not It is not a simple string replacement, but a new name** for the original data type , and it is used as a new data type.

macro definition with parameters

1. Basic introduction

(1) The C language allows macros to have parameters. The parameters in the macro definition are called "formal parameters", and the parameters in the macro call are called "actual parameters", which are somewhat similar to functions

(2) For macros with parameters, not only string replacements must be performed during the expansion process, but also formal parameters must be replaced with actual parameters

(3) The general form of a macro definition with parameters is **#define** macro name (formal parameter list) string , which can contain various formal parameters

(4) The general form of a macro call with parameters is: macro name (list of actual parameters);

#include <stdio.h>

//说明
//1.MAX就是带参数的宏
//2.(a,b)就是形参
//3.(a>b)?a:b 是带参数的宏对应字符串,该字符串中可以使用形参
#define MAX(a,b) (a>b) ? a : b
int main(){
    
    
	int x , y, max;
	printf("input two numbers: ");
	scanf("%d %d", &x, &y);
	
	//说明
	//1.MAX(x,y);调用带参数宏定义
	//2.在宏替换时(预处理,由预处理器),会进行字符串的替换,同时会使用实参,去替换形参
	//3.即MAX(x,y)宏替换后(x,y)?x:y
	max = MAX(x, y);
	printf("max=%d\n", max);
	getchar();
	getchar();
	return 0;
}

image-20221026205338803

2. Precautions and details

(1) In the macro definition with parameters, spaces can appear between formal parameters, but there cannot be spaces between the macro name and the list of formal parameters

Appear

#define MAX(a,b) (a>b)?a:b 如果写成了 #define MAX (a, b) (a>b)?a:b
将被认为是无参宏定义,宏名 MAX 代表字符串(a,b) (a>b)?a:b
而不是 : MAX(a,b) 代表 (a>b) ? a: b 了

(2) In the macro definition with parameters, memory will not be allocated for formal parameters, so it is not necessary to specify the data type . In the macro call, the actual parameters contain specific data, and they are used to replace the formal parameters, so the actual parameters must indicate the data type

(3) In the macro definition, the formal parameters in the string are usually enclosed in parentheses to avoid errors.

#include <stdlib.h>
#define SQ(y) (y)*(y) // 带参宏定义,字符串内的形参通常要用括号括起来以避免出错
int main(){
    
    
int a, sq;
printf("input a number: ");
scanf("%d", &a);
sq = SQ(a+1); // 宏替换 (a+1) * (a+1)
printf("sq=%d\n", sq);
system("pause");
return 0;}

The difference between a macro definition with parameters and a function

(1) Macro expansion is only a replacement of strings, and expressions will not be calculated; macros are processed before compilation, and they have no chance to participate in compilation and will not occupy memory.

(2) A function is a piece of code that can be reused. It will be compiled and memory will be allocated to it. Every time a function is called, the code in this memory is executed.

(3) Case description: It is required to use the function to calculate the square value, use the macro to calculate the square value, and summarize the difference between the two

Use the function to calculate the square value:

#include <stdio.h>
#include <stdlib.h>
int SQ(int y){
    
    //函数 ,求y的平方
	return ((y)*(y));
}
//#define SQ(y)((y)*(y))
int main(){
    
    
	int i=1;
	while(i<=5){
    
     // 1, 4, 9, 16, 25
	//分析
	//SQ(i++)宏调用 展开 ((i++)*(i++)) 这里 1 —> 3
		printf("%d^2 = %d\n",(i-1),SQ(i++));//先赋值i,后++
	}
	system("pause");
	return 0;
}

Operation result:

1^2 = 1
2^2 = 4
3^2 = 9
4^2 = 16
5^2 = 25

Calculate the square value with a macro:

#include <stdio.h>

#define SQ(y) ((y)*(y))

int main(){
    
    
    int i=1;
    while(i<=5){
    
    
        printf("%d^2 = %d\n", i, SQ(++i));
    }
    return 0;
}

operation result:

3^2 = 1
5^2 = 9
7^2 = 25

Highlights:

在用函数计算平方值中,先把实参 i 传递给形参 y,然后再自增 1,这样每循环一次 i 的值增加 1,所以最终要循环 5 次。

在用宏计算平方值中,宏调用只是简单的字符串替换,SQ(i++) 会被替换为 ((i++)*(i++)),这样每循环一次 i 的值增加 2,所以最终只循环 3 次。

宏和函数只是在形式上相似,本质上是完全不同的。

Summary of C language preprocessing commands

1. Common preprocessing instructions

A preprocessing directive is a line of code that begins with a # sign, which must be the first character on the line other than any whitespace characters. After # is the instruction keyword, any number of blank characters are allowed between the keyword and #, and the entire line of statement constitutes a preprocessing instruction, which will do some conversion on the source code before the compiler compiles .

image-20221026234753695

2. Precautions for using preprocessing instructions

image-20221026234928354

Guess you like

Origin blog.csdn.net/m0_53415522/article/details/127543548