Recently I was going through some of the source-codes of the best competitive programmers in the world. I found out that those people use a template while writing programs, preferably in C++
.
I have some difficulty understanding those programs because of the fact that they first create their own macros/types using #define
and typedef
. This is done to make the code more compact and to be able to type faster in competitions.
Now there are many instructions which are repeated many times while writing code, like for()
loops, declaring variables of type long
or long long
. So instead of writing a long instruction, I can create a macro. The same can be done for other statements to make the code more compact.
#include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> #define SC1(x) scanf("%lld",&x) #define SC2(x,y) scanf("%lld%lld",&x,&y) #define SC3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z) #define PF1(x) printf("%lld\n",x) #define PF2(x,y) printf("%lld %lld\n",x,y) #define PF3(x,y,z) printf("%lld %lld %lld\n",x,y,z) #define REP(i,n) for(long long i=0;i<(n);i++) #define FOR(i,a,b) for(long long i=(a);i<=(b);i++) #define FORD(i,a,b) for(long long i=(a);i>=(b);i--) #define WHILE(n) while(n--) #define MEM(a, b) memset(a, (b), sizeof(a)) #define ITOC(c) ((char)(((int)'0')+c)) #define MID(s,e) (s+(e-s)/2) #define SZ(a) strlen(a) #define MOD 1000000007 #define MAX 10000000005 #define MIN -10000000005 #define PI 3.1415926535897932384626433832795 #define TEST(x) printf("The value of \"%s\" is: %d\n",#x,x) const int INF = 1<<29; typedef long long ll; typedef unsigned long long ull; #define FILEIO(name) \ freopen(name".in", "r", stdin); \ freopen(name".out", "w", stdout);
I am interested in how the C/C++ pre-processor processes all those macros. I do understand the constants which are defined using macros like:
#define MOD 10000000007 #define MAX 10000000005 #define MIN -10000000005 #define PI 3.1415926535897932384626433832795
But how can I create a function macro which can reference to instruction, like:
#define SC1(x) scanf("%lld",&x) #define SC2(x,y) scanf("%lld%lld",&x,&y) #define SC3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z) #define PF1(x) printf("%lld\n",x) #define PF2(x,y) printf("%lld %lld\n",x,y) #define PF3(x,y,z) printf("%lld %lld %lld\n",x,y,z) #define REP(i,n) for(long long i=0;i<(n);i++) #define FOR(i,a,b) for(long long i=(a);i<=(b);i++) #define FORD(i,a,b) for(long long i=(a);i>=(b);i--) #define WHILE(n) while(n--) #define MEM(a, b) memset(a, (b), sizeof(a)) #define ITOC(c) ((char)(((int)'0')+c)) #define MID(s,e) (s+(e-s)/2) #define SZ(a) strlen(a) #define TEST(x) printf("The value of \"%s\" is: %d\n",#x,x)
By defining macros like the above, it is possible to increase the productivity, efficiency & speed of the programmer, right?
Now my questions are:
- When I define a macro like:
#define SC1(x) scanf("%lld",&x)
How the compiler process this macro. More generally how this instruction is being understood by the pre-processor when compiling/running the program.
- There are three different kinds of macros used for referencing three different versions of the loop:
#define REP(i,n) for(long long i=0;i<(n);i++) #define FOR(i,a,b) for(long long i=(a);i<=(b);i++) #define FORD(i,a,b) for(long long i=(a);i>=(b);i--)
In the above instructions, the variables which have to be computed first are enclosed in parenthesis ()
. What's the significance of parenthesis when working with macros?
- What does
\
mean in the following instruction:
#define FILEIO(name) \ freopen(name".in", "r", stdin); \ freopen(name".out", "w", stdout);
I know its a broad question related to use of macros in C and C++
, I really appreciate it, if someone can point me to the right direction on how to interpret/understand these macro instructions whenever encountered in a source-code so that I can modify and write my own macros for faster & efficient coding.
FORD
macro is defined slightly differently. You'll spend even more time adapting your thinking and fixing mistakes resulting from the difference every time yout switch codebases. All that to save - like 15 keystrokes (1-2 seconds for a competent typist). Thats not worth it.