directory search
Algorithms Algorithms(算法) bsearch bsearch_s qsort qsort_s Atomic operations Atomic operations library(原子操作库) ATOMIC_*_LOCK_FREE atomic_compare_exchange_strong atomic_compare_exchange_strong_explicit atomic_compare_exchange_weak atomic_compare_exchange_weak_explicit atomic_exchange atomic_exchange_explicit atomic_fetch_add atomic_fetch_add_explicit atomic_fetch_and atomic_fetch_and_explicit atomic_fetch_or atomic_fetch_or_explicit atomic_fetch_sub atomic_fetch_sub_explicit atomic_fetch_xor atomic_fetch_xor_explicit atomic_flag atomic_flag_clear atomic_flag_clear_explicit ATOMIC_FLAG_INIT atomic_flag_test_and_set atomic_flag_test_and_set_explicit atomic_init atomic_is_lock_free atomic_load atomic_load_explicit atomic_signal_fence atomic_store atomic_store_explicit atomic_thread_fence(线程围栏) ATOMIC_VAR_INIT kill_dependency memory_order(内存排序) C keywords auto(自动存储) break(跳出循环) C keywords(关键词) case char const(常量修饰符) continue default(预设运算式) do double(双精度浮点型) else enum(枚举类型) extern(全局变量) float(浮点数) for fortran goto(goto语句) if(if语句) inline(行内函式) int long(长整型) register(寄存器变量) restrict( restrict类型限定符) return short signed sizeof(sizeof运算符) static(静态变量) struct(结构体) switch(switch语句) typedef(typedef关键字) union(联合体) unsigned(无符号) void(空类型) volatile(volatile变量) while(while语句) _Alignas _Alignof _Atomic _Bool _Complex _Generic _Imaginary _Noreturn _Static_assert _Thread_local C language #define directive #elif directive #else directive #endif directive #error directive #if directive #ifdef directive #ifndef directive #include directive #line directive #pragma directive alignas(对齐指定符) Alternative operators and tokens(替代运算符和令牌) Analyzability Arithmetic operators Arithmetic types Array declaration(数组声明) Array initialization(阵列初始化) ASCII Chart Assignment operators(赋值运算符) types(atomic类型限定符) Basic concepts Bit fields(位域) break statement C language C Operator Precedence cast operator character constant(字符字面量) Comments(注释符) Comparison operators(比较运算符) compound literals(符合字面量) Conditional inclusion(条件包含) Conformance(一致性) const type qualifier(const 限定符) Constant expressions(常量表达) continue statement Declarations(声明) do-while loop Enumerations(枚举类型) Escape sequences(转义字符) Expressions(表达式) External and tentative definitions(外部和暂定的定义) File scope(文件范围) floating constant(浮点常量) for loop Function declarations(函数声明) Function definitions(函数声明) Functions Generic selection泛型选择 goto statement Identifier(标示符) if statement Implicit conversions(隐式转换) Increment/decrement operators(前置/后置操作符) Initialization(初始化) inline function specifier(内联函式) integer constant Lifetime(生命期) Logical operators(逻辑运算符) Lookup and name spaces Main function(主函式) Member access operators(会员接入运营商) Memory model Objects and alignment(字节对齐) Order of evaluation(评估顺序) Other operators Phases of translation(翻译阶段) Pointer declaration Preprocessor(预处理) restrict type qualifier(restrict类型限定符) return statement Scalar initialization(标量类型初始化) Scope(范围) sizeof operator(sizeof运算符) Statements(陈述) static assert declaration(静态断言声明) Static storage duration(静态存储周期) Storage-class specifiers(存储类说明符) string literals(字符串字面量) Struct and union initialization(结构体与联合体初始化) Struct declaration(结构体声明) switch statement Thread storage duration(线程存储时间) Type Type(类型) Typedef declaration(Typedef声明) Undefined behavior(未定义行为) Union declaration(联合体声明) Value categories(值类别) Variadic arguments(变长参数宏) volatile type qualifier(volatile 类型限定符) while loop _Alignof operator _Noreturn function specifier Date and time asctime(asctime函数) asctime_s clock CLOCKS_PER_SEC clock_t ctime(ctime函数) ctime_s Date and time utilities(日期和时间库) difftime(计算两个时间的间隔) gmtime gmtime_s localtime localtime_s mktime(将时间结构数据转换成经过的秒数的函数) strftime(格式化输出时间函数) time timespec timespec_get time_t tm wcsftime(格式化时间宽字符) Dynamic memory management aligned_alloc C memory management library(内存管理库) calloc free(释放动态分配空间的函数) malloc(动态分配内存空间的函数) realloc(重新分配内存空间的函数) Error handling abort_handler_s assert(断言) constraint_handler_t errno(错误报告) Error handling(错误处理) Error numbers(错误个数) ignore_handler_s set_constraint_handler_s static_assert File input/output clearerr(清除/复位) fclose feof ferror fflush(清空文件缓冲区) fgetc fgetpos fgets fgetwc fgetws File input/output fopen fopen_s fprintf fprintf_s fputc fputs fputwc fputws fread freopen freopen_s fscanf fscanf_s fseek fsetpos ftell fwide fwprintf fwprintf_s fwrite fwscanf fwscanf_s getc getchar gets gets_s getwchar perror printf printf_s putc putchar puts putwc putwchar remove rename rewind scanf scanf_s setbuf setvbuf snprintf sprintf sscanf sscanf_s swprintf swprintf_s swscanf swscanf_s tmpfile tmpfile_s tmpnam tmpnam_s ungetc ungetwc vfprintf vfprintf_s vfscanf vfscanf_s vfwprintf vfwprintf_s vfwscanf vfwscanf_s vprintf vprintf_s vscanf vscanf_s vsnprintf vsprintf vsscanf vsscanf_s vswprintf vswprintf_s vswscanf vswscanf_s vwprintf vwprintf_s vwscanf vwscanf_s wprintf wprintf_s wscanf wscanf_s Localization support lconv LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY LC_NUMERIC LC_TIME localeconv Localization support setlocale Numerics abs acos acosf acosh acoshf acoshl acosl asin asinf asinh asinhf asinhl asinl atan atan2 atan2f atan2l atanf atanh atanhf atanhl atanl cabs cabsf cabsl cacos cacosf cacosh cacoshf cacoshl cacosl carg cargf cargl casin casinf casinh casinhf casinhl casinl catan catanf catanh catanhf catanhl catanl cbrt cbrtf cbrtl ccos ccosf ccosh ccoshf ccoshl ccosl ceil ceilf ceill cexp cexpf cexpl cimag cimagf cimagl clog clogf clogl CMPLX CMPLXF CMPLXL Common mathematical functions complex Complex number arithmetic conj conjf conjl copysign copysignf copysignl cos cosf cosh coshf coshl cosl cpow cpowf cpowl cproj cprojf cprojl creal crealf creall csin csinf csinh csinhf csinhl csinl csqrt csqrtf csqrtl ctan ctanf ctanh ctanhf ctanhl ctanl div double_t erf erfc erfcf erfcl erff erfl exp exp2 exp2f exp2l expf expl expm1 expm1f expm1l fabs fabsf fabsl fdim feclearexcept fegetenv fegetexceptflag fegetround feholdexcept feraiseexcept fesetenv fesetexceptflag fesetround fetestexcept feupdateenv FE_ALL_EXCEPT FE_DFL_ENV FE_DIVBYZERO FE_DOWNWARD FE_INEXACT FE_INVALID FE_OVERFLOW FE_TONEAREST FE_TOWARDZERO FE_UNDERFLOW FE_UPWARD Floating-point environment float_t floor floorf floorl fma fmaf fmal fmax fmaxf fmaxl fmin fminf fminl fmod fmodf fmodl fpclassify FP_INFINITE FP_NAN FP_NORMAL FP_SUBNORMAL FP_ZERO frexp frexpf frexpl HUGE_VAL HUGE_VALF HUGE_VALL hypot hypotf hypotl I ilogb ilogbf ilogbl imaginary imaxabs imaxdiv INFINITY isfinite isgreater isgreaterequal isinf isless islessequal islessgreater isnan isnormal isunordered labs ldexp ldexpf ldexpl ldiv lgamma lgammaf lgammal llabs lldiv llrint llrintf llrintl llround llroundf llroundl log log10 log10f log10l log1p log1pf log1pl log2 log2f log2l logb logbf logbl logf logl lrint lrintf lrintl lround lroundf lroundl MATH_ERREXCEPT math_errhandling MATH_ERRNO modf modff modfl nan NAN nanf nanl nearbyint nearbyintf nearbyintl nextafter nextafterf nextafterl nexttoward nexttowardf nexttowardl Numerics pow powf powl Pseudo-random number generation rand RAND_MAX remainder remainderf remainderl remquo remquof remquol rint rintf rintl round roundf roundl scalbln scalblnf scalblnl scalbn scalbnf scalbnl signbit sin sinf sinh sinhf sinhl sinl sqrt sqrtf sqrtl srand tan tanf tanh tanhf tanhl tanl tgamma tgammaf tgammal trunc truncf truncl Type-generic math _Complex_I _Imaginary_I Program support abort atexit at_quick_exit exit EXIT_FAILURE EXIT_SUCCESS getenv getenv_s jmp_buf longjmp Program support utilities quick_exit raise setjmp SIGABRT SIGFPE SIGILL SIGINT signal SIGSEGV SIGTERM sig_atomic_t SIG_DFL SIG_ERR SIG_IGN system _Exit Strings atof atoi atol atoll btowc c16rtomb c32rtomb char16_t char32_t isalnum isalpha isblank iscntrl isdigit isgraph islower isprint ispunct isspace isupper iswalnum iswalpha iswblank iswcntrl iswctype iswdigit iswgraph iswlower iswprint iswpunct iswspace iswupper iswxdigit isxdigit mblen mbrlen mbrtoc16 mbrtoc32 mbrtowc mbsinit mbsrtowcs mbsrtowcs_s mbstate_t mbstowcs mbstowcs_s mbtowc memchr memcmp memcpy memcpy_s memmove memmove_s memset memset_s Null-terminated byte strings Null-terminated multibyte strings Null-terminated wide strings strcat strcat_s strchr strcmp strcoll strcpy strcpy_s strcspn strerror strerrorlen_s strerror_s Strings library strlen strncat Thread support call_once cnd_broadcast cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait mtx_destroy mtx_init mtx_lock mtx_plain mtx_recursive mtx_timed mtx_timedlock mtx_trylock mtx_unlock once_flag ONCE_FLAG_INIT thrd_busy thrd_create thrd_current thrd_detach thrd_equal thrd_error thrd_exit thrd_join thrd_nomem thrd_sleep thrd_success thrd_timedout thrd_yield Thread support library thread_local tss_create tss_delete TSS_DTOR_ITERATIONS tss_get tss_set Type support Boolean type support library Fixed width integer types FLT_EVAL_METHOD FLT_ROUNDS max_align_t NULL Numeric limits offsetof ptrdiff_t size_t Type support Variadic functions Variadic functions va_arg va_copy va_end va_list va_start
characters

预处理器支持文本宏替换和类似功能的文本宏替换。

句法

#define identifier replacement-list(optional)

(1)


#define identifier( parameters ) replacement-list

(2)


#define identifier( parameters, ... ) replacement-list

(3)

(since C99)

#define identifier( ... ) replacement-list

(4)

(since C99)

#undef  identifier

(5)


说明

#define 指令

#define指令定义的标识符作为一个宏,即它们指示编译器替换替换列表标识符的所有连续出现,其可以额外地任选地进行处理。如果标识符已经被定义为任何类型的宏,那么该程序是格式不正确的,除非定义相同。

类似于对象的宏

类似于对象的宏将每个定义的标识符替换为替换列表。#define指令的版本(1)的行为完全如此。

函数式的宏

类似功能的宏将替换列表中的每个出现的已定义标识符替换为另外的一些参数,然后替换替换列表中任何参数的相应出现。

函数式宏调用的语法类似于函数调用的语法:宏名称的每个实例后跟一个(作为下一个预处理标记引入由替换列表替换的标记序列)序列由匹配)令牌终止,跳过中间匹配的左右括号对。

参数的数量必须与宏定义(参数)中参数的数量相同或程序不合格。如果标识符不是功能符号,也就是说本身没有括号,它根本不会被替换。

#define指令的版本(2)定义了一个简单的函数式宏。

#define指令的版本(3)定义了一个具有可变数量参数的函数式宏。可以使用__VA_ARGS__标识符访问附加参数,然后使用标识符来替换标识符,然后使用标识符替换它们。

#define指令的版本(4)定义了一个类似函数的宏,其中包含可变数量的参数,但没有常规参数。只能使用__VA_ARGS__标识符访问参数,然后使用标识符替换标识符,并将标识符替换。

注意:如果类似函数的宏的参数包含未被左右括号(如macro(array[x = y, x + 1]))的匹配对保护的逗号,则逗号将被解释为宏参数分隔符,导致由于参数计数不匹配导致的编译失败。

# and ## operators

在函数式宏中,#替换列表中的标识符之前的运算符通过参数替换运行标识符,并将结果封装在引号中,从而有效地创建字符串文字。另外,预处理器会添加反斜杠以避免嵌入的字符串文字(如果有的话)引用,并在必要时将字符串中的反斜杠加倍。所有前导空白和尾随空白都被删除,并且文本中间的任何空白序列(但不在嵌入的字符串文字内)被折叠为单个空格。这个操作被称为“串化”。如果字符串化的结果不是有效的字符串,则行为是未定义的。

当#在__VA_ARGS__之前出现时,整个展开的__VA_ARGS__用引号引起来:#define showlist(...)puts(#__ VA_ARGS__)showlist(); //展开为puts(“”)showlist(1,“x”,int); //展开为puts(“1,\”x \“,int”)

(自C99以来)

##在替换列表中的任何两个连续标识符之间的运算符运行两个标识符上的参数替换,然后连接结果。这个操作被称为“连接”或“令牌粘贴”。只有形成一个有效令牌的令牌可以被粘贴:形成一个更长的标识符的标识符,形成一个数字的数字,或运算符,+=形成一个+=。评论不能通过粘贴来创建,/并且*因为在考虑宏替换之前从文本中删除评论。如果连接的结果不是有效的标记,则行为是未定义的。

注意:有些编译器提供了一个允许##出现在逗号之后和__VA_ARGS__之前的扩展,在这种情况下,当__VA_ARGS__非空时,##什么也不做,但当__VA_ARGS__为空时删除逗号:这使得可以定义宏等fprintf (stderr, format, ##__VA_ARGS__)

#undef directive

#undef指令取消定义标识符,即它通过#define指令取消标识符的先前定义。如果标识符没有关联的宏,则该指令被忽略。

预定义的宏

任何翻译单元中都预先定义了以下宏名称:

__STDC__

expands to the integer constant 1. This macro is intended to indicate a conforming implementation  (macro constant)

__STDC_VERSION__ (C95)

expands to an integer constant of type long whose value increases with each version of the C standard:   199409L (C95)   199901L (C99)   201112L (C11)  (macro constant)

__STDC_HOSTED__ (C99)

expands to the integer constant 1 if the implementation is hosted (runs under an OS), 0 if freestanding (runs without an OS)  (macro constant)

__FILE__

expands to the name of the current file, as a character string literal, can be changed by the #line directive  (macro constant)

__LINE__

expands to the source file line number, an integer constant, can be changed by the #line directive  (macro constant)

__DATE__

expands to the date of translation, a character string literal of the form "Mmm dd yyyy". The name of the month is as if generated by asctime and the first character of "dd" is a space if the day of the month is less than 10  (macro constant)

__TIME__

expands to the time of translation, a character string literal of the form "hh:mm:ss", as in the time generated by asctime()  (macro constant)

  • 199409L (C95)

  • 199901L (C99)

  • 201112L (C11) (macro constant)

 \_\_STDC\_HOSTED\_\_

(C99)

1如果实施托管(在 OS 下运行),0则   扩展为整数常量,如果是独立的(无 OS 的情况下运行)

(macro constant)     __FILE__

扩展为当前文件的名称,作为字符串文字,可以通过#line 指令进行更改

(macro constant)     __LINE__

展开为源文件行号,一个整数常量,可以通过#line 指令进行更改

(macro constant)     __DATE__

扩展到翻译日期,形式为 “Mmm dd yyyy” 的字符串文字。月份的名称如同生成的一样,如果asctime月份的日期小于10,则“dd”的第一个字符是空格

(macro constant)     __TIME__

扩展到翻译时,形式为 “hh:mm:ss” 形式的字符串文字,如在 asctime()

(macro constant)

以下附加宏名称可能由实现预定义:

__STDC_ISO_10646__ (C99)

expands to an integer constant of the form yyyymmL, if wchar_t uses Unicode, the date indicates the latest revision of Unicode supported  (macro constant)

__STDC_IEC_559__ (C99)

expands to 1 if IEC 60559 is supported  (macro constant)

__STDC_IEC_559_COMPLEX__ (C99)

expands to 1 if IEC 60559 complex arithmetic is supported  (macro constant)

__STDC_UTF_16__ (C11)

expands to 1 if char16_t use UTF-16 encoding  (macro constant)

__STDC_UTF_32__ (C11)

expands to 1 if char32_t use UTF-32 encoding  (macro constant)

__STDC_MB_MIGHT_NEQ_WC__ (C99)

expands to 1 if wide character encoding of the basic character set may not equal their narrow encoding, such as on EBCDIC-based systems that use Unicode for wchar_t  (macro constant)

__STDC_ANALYZABLE__ (C11)

expands to 1 if analyzability is supported  (macro constant)

__STDC_LIB_EXT1__ (C11)

expands to an integer constant 201112L if bounds-checking interfaces are supported  (macro constant)

__STDC_NO_ATOMICS__ (C11)

expands to 1 if atomic types and atomic operations library are not supported  (macro constant)

__STDC_NO_COMPLEX__ (C11)

expands to 1 if complex types and complex math library are not supported  (macro constant)

__STDC_NO_THREADS__ (C11)

expands to 1 if multithreading is not supported  (macro constant)

__STDC_NO_VLA__ (C11)

expands to 1 if variable-length arrays are not supported  (macro constant)

这些宏的值(除了__FILE____LINE__)在整个翻译单元中保持不变。尝试重新定义或取消定义这些宏会导致未定义的行为。

预定义变量__func__(详见函数定义)不是预处理器宏,即使它有时与__FILE__和__LINE__一起使用,例如通过 assert。

(自C99以来)

#include <stdio.h> //make function factory and use it#define FUNCTION(name, a) int fun_##name(int x) { return (a)*x;} FUNCTION(quadruple, 4)FUNCTION(double, 2)
 #undef FUNCTION
#define FUNCTION 34#define OUTPUT(a) puts( #a )
 int main(void){    printf("quadruple(13): %d\n", fun_quadruple(13) );    printf("double(21): %d\n", fun_double(21) );    printf("%d\n", FUNCTION);    OUTPUT(million);               //note the lack of quotes}

输出:

quadruple(13): 52double(21): 4234million

参考

  • C11标准(ISO / IEC 9899:2011):

    • 6.10.3宏替换(p:166-173)

    • 6.10.8预定义的宏名称(p:175-176)

  • C99标准(ISO / IEC 9899:1999):

    • 6.10.3宏替换(p:151-158)

    • 6.10.8预定义的宏名称(p:160-161)

  • C89 / C90 标准(ISO / IEC 9899:1990):

    • 3.8.3宏替换

    • 3.8.8预定义的宏名称

Previous article: Next article: