On the C ++ preprocessor

1 Overview

Pre-order is an order at the beginning of our program to begin with the # character. Why is it called pre-order? Because these commands is the first step at compile time on the implementation of, not into assembly code.

Step compiler code:

  1. Pretreatment. Processing # include, # define commands and delete comments, so no matter how the first step will no longer write CE.

  2. Compilation. Really will compile code syntax analysis (opened O2 will change some of) and generate an assembly file.

  3. compilation. The assembly code into machine code.
  4. link. Relocation, according to computer link libraries, the executable file

Use -E, -S, -cmay choose to perform only the step 1, steps 1-2, steps 1-3. If there are doubts about the knowledge of this article, you may choose to use g++ -E 1.cpp -o 1.ito obtain the pre-processed .idocument the experience. Further -Salso be used to obtain the assembly code.

Most of the pre-command in the OI in little use, but there are powerful preprocessor.

#Symbol should be the first non-blank character on the line. However, you can also play \the content to the next line, just as a comment.

#define pi 3.14159 \
26535
//This is an \
example

This put the move on the next line content.

Luo Gu editor would not be so displayed, but the local editor you can find the next line has become a comment or pretreatment style.

Common pre-orders are as follows:

#include 包含头文件
#ifdef 或 #if defined 如果定义了一个宏, 就执行操作
#ifndef 或 #if !defined 如果没有定义一个宏,就指执行操作
#define 定义一个宏
#undef 删除一个宏
#pragma 自定义编译器选项,指示编译器完成一些事

Here are three of the most commonly used Preprocessing: #include, #define,#pragma

2. #include

This is the most common file contains commands.

No matter how powerful you are, what things can be handwritten, but also need#include <cstdio>

Command is essentially a function of the specified file, variables, macros, and all imported, can be understood as the entire contents of the file to copy and paste into your code in the.

However, if it is simply pasted, # include repeated twice should have defined CE son. But the standard library use macros to avoid this (see later). Note that we also have to write the header file.

Question 0: #include angle brackets must be connected to it?

In fact, the #includecommand is not necessary to use angle brackets, quotation marks is totally acceptable.

The difference is that the quotes will give priority to look at the file to be compiled, the call will not find the standard library file.

Of course, for OIer terms, #include <cstdio>and #include "cstdio"there would be no difference, but this time the angle brackets more standardized.

When developing your own games using C ++, for ease of management, you can use the same function similar to a separate file saved as standard with a library. It will be included when needed, then you need to use quotation marks.

Question 1: Why not add .h header files when referencing standard library?

In fact, the C language to be added, can only write #include <stdio.h>or#include <math.h>

C ++ in the extension of these documents removed and preceded by a c example#include <cmath>

But these traditional library if you use the old wording, can still be had compiled, but not standardized.

But for new content (such as C ++, iostreamand stack) can not be added .hup.

Someone tried, say #include <string.h>can! But string.hit corresponds to the C language of cstringthe new library instead of C ++ that string. The former use is not defined stringtype. cstringLibrary is to provide some char array of functions and function memory operations such as memset, memcpy, strlen.

Question 2: universal header files really powerful?

Now NOI) (P already supports universal header files #include <bits/stdc++.h>.

(Note the forward slash is not a backslash wrong possible CE)

In fact what he is impossible to contain your mind completely, but you can absolutely have to stuff inside.

C++11Also included in the new random, unordered_mapsuch as libraries.
See stdc ++. H original file

Although it can not be universal, OI was indeed completely sufficient.

Rumor! ! ! Universal header files and does not slow down the running speed, increase the memory is almost negligible. Compiled main thing was not used will be optimized away.

And you can always bring a dozen header file, say ten thousand bad again, there is no convincing

Of course, it is possible to increase the size of the source code and compile time, and then the eggs

Question 3: Why do I see other people have a magical operation in the middle of the program include files?

He said before #includethe nature of the specified file is copied into this line, so if it is written in the function of this command, it is only a function of this effective.

void func()
{
    #include "test.h"
    mmm();//可以使用test.h里的函数
}

int main()
{
    func();
    mmm()//CE。不能使用test.h里的函数。
}

But in OI can not be so, because the standard library also involves the issue of the namespace.

Quetion 4: Write your own header files in the end is how to use?

According to standard, then, .hfor macros and functions to store large masses, variable declaration (that is, the function name and parameter list of the first row of function), and the same name as .cppthe concrete realization of storage function. .hI wrote a #include "test.cpp". The main program includes test.h can be used as long as the function of the library.

However, in order to save effort, we can .hdirectly in the definition of good function, you can choose directly in the main program #include "test.cpp". Contains the essence of the copy and paste commands, write also no problem.

Use variable names do not use the universal header files :y1, next, time, rand

Including many common words are not the best, some Windows can, but will when evaluating CE.

3. #define

#Define macro definition command is called, the code for the replacement string. Is the most useful preprocessing directives

1. macro without parameters

#define MAX 10000
if (9874 > MAX)
    return 0;

The code is defined macros MAX, phrase after "MAX" represents 10000. if the expression is false.

Const This method may be used instead to define constants, and only the code replacement, the runtime does not occupy space. It can also be used to simplify the standard library function names long.

Also, if this constant need to perform multiple operations (such as modulus), is said to be written const is faster, through individuals do not fully tested is indeed the case, but the efficiency of the difference is small, so do not too much care about, or see themselves more what kind of writing like.

note:

1. #define does not replace a macro strings and annotations (nonsense)

2. The need to completely match macro Alternatively, as will be defined macro "super", "supermarket" section is not replaced.

2. Macro with arguments

In fact, with macro functions, you may have parameters.

Example: seeking the perimeter and the area with the radius of the circle.

#define pi 3.14159
#define AREA(i) i*i*pi

double d;

int main()
{
    cin >> d;
    cout << AREA(d)<< endl ;
    return 0;
}

When we write a macro like this AREA function of the form, after AREA (i) appears,
first found in brackets 2, that is, i = 2, then do the replacement.

Since only strings Alternatively, it can not only define #define constants you can also define the expression, function, or even code segments.

#define sum(a,b,c) (a)+(b)+(c)
#define max(a,b) (a>b)?(a):(b)
#define fors(a,b) for(int i=(a);i<=(b);i++)

Using the macro definition makes code much easier to understand, a #define max while other functions. Faster than function, but not much faster.

note:

#Define command macro command is the first word, the rest of the macro body.

#define int long long
#define abc def ghi \
jkl
#define register

In the first sentence, the first alternative is an int, i.e. after int Representative long long.

In the second sentence, only to be replaced as a macro body abc, abc is after def ghi jkl, only backslash wrap effect.

In the third sentence, the program in all registerwill be deleted, it can be used for debugging.

Special case (not completely replace the string, thanks @Black_white_Tony dalao):

We all know that vector <pair<int,int>>because >> is recognized as a right and CE must fill spaces. But if you write:

#define pii pair<int,int>
vector <pii> a;

But it can properly compile, because if define the character and the last after the first character can constitute a new operator, will automatically add a space. You can use the g++ -Einstructions to see some of the more thorough.

Two new operators operator configuration spaces:<< >> -> ++ && += >=

This is perhaps the exception to STL STL set of design problems now.

Note: C++11there could be written directly vector <pair<int,int>>, but if you use a macro definition file will still be here in the first step of pretreatment plus spaces.

3. Advanced Applications macro

##: Left and right ends of the connection string

#: The back of the parameter becomes a string (i.e., plus the force "")

#define a(x) p##x
#define b(x) #x

int p1 = 3, p2 = 4;
  
int main()
{
    printf("%d %d\n",a(1),a(2));
    puts(b(qwqwq));
}
//Output:
//3 4
//qwqwq

The more common abbreviation is used for, to avoid problems caused b change brings.

#define F(i, a, b) for(int i=(a),end##i=(b); i<=end##i; i++)

#ifdef If you define macros

#ifndef If you do not define a macro

#endifTermination of the above two sentences (equivalent to closing parenthesis)

In the standard library, each including a header file, this file will define a header indicates that the file has been included in the macro if the file contains the second time, #ifndefis false is not executed, it will skip the file, so you can avoid repeating contain lead CE.

Some macros are compiled in a different environment on a defined, you can use these to do interesting things.

#ifndef ONLINE_JUDGE
    freopen("testdata.in","r",stdin);
    freopen("testdata.out","w",stdout);
#endif
//很多OJ(包括洛谷)都有这个宏

Alternatively, you can define a macro debug, the debug output statements used at the beginning of #ifndefthe enclosed, so you only need to remove the debug output annotation line.

Other predefined macros :( taken from cppreference)

__cplusplus //C++版本号
__FILE__ //文件名
__DATE__ //编译日期
__TIME__ //编译时间
__LINE__ //这一行的行号

4. Macro revocation

Definable macros will be able to cancel, use #undef macro names can be directly connected to revoke the macro (including predefined).

#define sum(a,b) a+b
#define e 2.718
int a=sum(9,6);
double b=e*3;
#undef sum(a,b)
#undef e
#undef __cplusplus

The drawback of macro

Acer is convenient to use, but there are many disadvantages.

I. priority change operation
#define DEF 2+3
int a = DEF+5;
int b = DEF*7;

DEF 2 + 3 in the form of directly into the not converted to 5

In the definition of A, a is to be interpreted as "5 + 2 + 3", a value of 10.

However, to be construed as B "2 * 7 + 3", multiplication first count value of 23, we want not 35.

The solution is to put parentheses around parameters

II. No fixed data type
#define MAX 1e6
int a[MAX];

At this point it would CE. Because 1e6 is a double type, the array size can only int, since the text is replaced MAX here does not cause the type of conversion.

This is plus (int) in front of, or defined constants using const.

4. #pragma

We find the optimal solution of a question time, the fastest man (if not hit the table) #pragma often have dozens of lines to card often. So what is the use of this command? What is the principle card often is it?

#pragmaCommand can specify compiler options, or let the compiler do some command. Very powerful, there is only a very superficial introduction.

Part excerpt from Baidu Encyclopedia.

1. #pragma once

Add at the beginning of the header file, you can tell the compiler to compile the file once the most, can also be used to prevent duplicate include the header file. Than previously #ifndefeasy to use, but the standard library is useless.

2. #pragma message()

Let the compiler output string in parentheses, with the #ifdefpossible outputs specific information at compile time.

3. #pragma comment ()

Itself for the linked file, OI can be used to manually expand in the stack (but not necessarily helpful)

#pragma comment(linker,"/STACK:1024000000,1024000000")

4. #pragma GCC target()

The searched the entire network no precise definition, is probably the brackets what is recognized as instruction. Faster than the speed command function, thereby accelerating.

#pragma GCC target("popcnt")Built-in function allows __builtin_popcount () is more than double the speed.

In addition, if you want to use the instruction set can also be used on the instruction set including this instruction.

#pragma GCC target("avx,avx2,sse,sse2,sse3,sse4.1,sse4.2")

5. #pragma pack() & pop()

A structure for aligning

//#pragma pack(4)
struct Node
{
    int a;
    long long b;
}x;

Originally Each variable that is aligned with a maximum structural body, such as the example on int aligned with the long long, is also 8 bytes. So sizeof x = 16.

However, if there #pragma phrase, each variable will be aligned and 4, the number of bytes int 4, long long due to the inherently greater than 4 was ignored sizeof x = 12. This will save space to a certain extent.

But the fact is aligned more efficient, so x bigger good.

pop () may be used to cancel the pack () instruction

6. #pragma GCC optimize()

The brackets compiled into a string parameter, which is equivalent to customize the compiler parameters.

If you enter a number, then it will be O1 / O2 / O3 optimization. Use this command to turn on the compiler optimization comes.

But the only compiler optimization parameters, such as -ospecify the file name can not certainly added to the inside.

Finally comes with 40 lines to optimize the network widely circulated:

#pragma GCC target("sse,sse2,sse3,sse4.1,sse4.2,popcnt,abm,mmx,avx")
#pragma comment(linker,"/STACK:102400000,102400000")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")

note:

  1. Such optimal results metaphysics, vary, sometimes quite fierce at times that are not used, are also associated with the build environment. But the worst case there is no use, the code will not compile environment CE.
  2. Since the O2 / O3 / Ofast optimization has reached the rewrite cycle, remove redundant code such as the degree of Armageddon, and it is easy to change the intent of the code results in an error metaphysics. When using these optimized must ensure their code specifications, otherwise there will be metaphysical problems.
  3. Do not know NOI) (P can not be used, not the best (and you can not back down)

5. Others

There are some commands here to spend a few lines of introduction.

#error //在这一行显示一个CE信息,并中断编译
#warning //在这一行显示警告信息
#line //指定下一行的行号
#if //如果满足则执行,后面应接布尔表达式,以#endif结尾
#elif //#if语句的分支

Sahua end, thanks to accompany

Guess you like

Origin www.cnblogs.com/ofnoname/p/11621345.html