元始天尊 发表于 2014-10-10 23:17:22

预编译指令学习心得

注意,这不是演习!!!那么问题来了(编译器技术哪家强?),虽然预编译指令是老生常谈了,不过仍然有一些之前没见过,这里就一一道来。

    这里暂且说一个MSDN的小技巧,在线版本有时网页上没提供选择语言的选项,比如:http://msdn.microsoft.com/ZH-CN/library/vstudio/ms177415(v=vs.110).aspx 这时注意看中间ZH-CN,若改成EN-US那么就变成英文的了,翻译版的经常很生硬,不知道在说些什么,然而看翻译版的在一定程度上可以提高效率。所以我经常会切换语言。

Variadic宏
   Variadic宏是可变参的类函数宏,在使用该宏时需要将省略号作为宏定义的最后一个形参,并在宏定义中加入替换标识符__VA_ARGS__,编译器会将_VA_ARGS_替换为省略号对应的参数,包括参数间的逗号。
   C标准规定省略号至少代表一个参数,这样该宏才不会被解释成一个逗号结尾的表达式(不过VS里没有按照标准实现!!!)

以带有颜色区分的格式查看复制到剪贴板// variadic_macros.cpp
#include <stdio.h>
#define EMPTY

#define CHECK1(x, ...) if (!(x)) { printf(__VA_ARGS__); }
#define CHECK2(x, ...) if ((x)) { printf(__VA_ARGS__); }
#define CHECK3(...) { printf(__VA_ARGS__); }
#define MACRO(s, ...) printf(s, __VA_ARGS__)

int main()
{
   CHECK1(0, "here %s %s %s", "are", "some", "varargs1(1)\n");
   CHECK1(1, "here %s %s %s", "are", "some", "varargs1(2)\n");   // won't print

   CHECK2(0, "here %s %s %s", "are", "some", "varargs2(3)\n");   // won't print
   CHECK2(1, "here %s %s %s", "are", "some", "varargs2(4)\n");

   // always invokes printf in the macro
   CHECK3("here %s %s %s", "are", "some", "varargs3(5)\n");

   MACRO("hello, world\n");
   // MACRO("error\n", EMPTY);   would cause C2059
}

结果:
here are some varargs1(1)
here are some varargs2(4)
here are some varargs3(5)
hello, world

注意__VA_ARGS__只能在宏里用,不能用于函数。
另外提供一个小技巧,在命令提示符里你怎么复制粘贴呢?
在IO等待状态时,复制操作可以在cmd窗口右键选择“标记”,然后选择一个正方形区域,再点击右键就复制下来这段文本了,而粘贴则是在其他地方复制数据到剪贴板之后,在cmd中右键点粘贴
在CMD运行状态时右键不奏效,因此需要点窗口系统菜单(左上角图标),选择“编辑”->“标记”,之后选择一块区域操作即可。

宏和C++
预定义宏:
__DATE__当前日期
__TIME__当前时间
__FILE__当前文件名
__COUNTER__计数器,每次使用该宏值递增
__CPLUSPLUS C++程序
_DEBUG 调试版本
_DLL 动态链接库
__FUNCDNAME__ __FUNCSIG__ __FUNCTION__ 函数信息:

void exampleFunction()
{
    printf("Function name: %s\n", __FUNCTION__);
    printf("Decorated function name: %s\n", __FUNCDNAME__);
    printf("Function signature: %s\n", __FUNCSIG__);
   
    // Sample Output
    // -------------------------------------------------
    // Function name: exampleFunction
    // Decorated function name: ?exampleFunction@@YAXXZ
    // Function signature: void __cdecl exampleFunction(void)
}


预处理器运算符和关键字
运算符
#将宏参数转换为双引号字符串
#@ 将宏参数转换为单引号字符串(长度有限)
## 连接标识符

#pragma关键字
alloc_text将指定符号装入指定段
bss_seg code_seg const_seg data_seg init_seg 装入指定段
comment(lib,"*.dll")链接指定库
comment(linker,"")设置链接选项
页: [1]
查看完整版本: 预编译指令学习心得