c #define
macro substitution, define alias name for something, include:
#define
#undef
#ifdef / #ifndef / #endif
------
#define
define an alias name for value / expression / .. ,
format:
#define name replacement_text
how it work:
before compile, the name will be replace by the replacement_text,
name:
name could be anything, by conversion, name for value use uppercase, for function use lowercase,
replacement_text:
could be anything,
function define:
if name is a function(..), then you can pass param to it,
in pre-compile stage, the param is replaced with the variable name you pass,
the param of function has no specific type, you can pass any type as long as the program is correct,
evaluate twice:
the param will be envalued twice, so don't pass param that has side effect, e.g. i++,
order of evaluate:
the param is replaced literally, so use parentheses to make sure correct evaluate order,
e.g.
#define square(x) x * x /* wrong */
#define square(x) (x) * (x) /* ok */
call square(i+1)
#:
when #define a function, in the expression, when put # before param, the param will be evaluated and put into "",
e.g.
#define connect_num_to_str(a,b) #a #b /* connect numbers */
char *s = connect_num_to_str(100,200);
printf("%s\n", s); /* "100200" */
##:
when #define a function, in the expression, when put ## before param,
the parameter is replaced by the actual argument name, the ## and surrounding white space are removed, and then the result is rescanned,
this is a way to create a specify variable name,
## can't appear at start or end of the expression,
e.g.
#define another_var_by_prefix(pre,suf) pre ##suf /* specify a variable name by connect string */ // first s ##2, then s2, so s3 = s2 char *s3 = another_var_by_prefix(s,2);
------
#undef
format:
#undef NAME
usually, this is used to make sure a function_name is not a macro,
------
#ifdef / #ifndef / #endif
check whether a macro is defined, and execute statements,
format:
#ifdef / #ifndef NAME
...
#endif
similar to:
#if defined(name)
#if !defined(name)
multiple define:
you can define a NAME more than once,
if you define a NAME more than once with different value, it's ok, but you might get a warning when compile,
------
defined(name)
used with #if, to detecact whether a macro is defined,
format:
#if defined(name) / #if !defined(name)
#if defined name / #if !defined name
------
code
define_test.c:
#include <stdio.h> #define MY_NAME "eric" #define square(x) (x) * (x) #define multiply(a,b) (a) * (b) #define multiply_wrong(a,b) a * b /* this is wrong, the order has problem */ #define connect_num_to_str(a,b) #a #b /* connect numbers */ #define another_var_by_prefix(pre,suf) pre ##suf /* specify a variable name by connect string */ #define swap(t,x,y) {t _z = x; x = y; y=_z;} /* exchange value of x and y, t should be a type, can use typeof() to get a type, */ #ifdef MY_AGE #undef MY_AGE /* undefine a macro name */ #endif #ifndef MY_AGE #define MY_AGE 25 /* define a micro name, if not defined yet */ #endif main() { printf("%s,%d\n",MY_NAME,MY_AGE); printf("%d\n",square(MY_AGE+1)); printf("%d\n",multiply(MY_AGE+1,MY_AGE-1)); printf("%d\n",multiply_wrong(MY_AGE+1,MY_AGE-1)); char *s = connect_num_to_str(100,200); printf("%s\n", s); char *s2 = "a" "b"; printf("%s\n", s2); char *s3 = another_var_by_prefix(s,2); printf("%s\n", s3); int x = 10, y=20; swap(typeof(x),x,y); printf("%d,%d\n",x,y); }
------