c/c++ 宏

int32位 posted @ Mar 02, 2014 10:38:07 AM in c/cpp , 1456 阅读
转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!

c语言中宏还是挺重要的东西,c++中由于有了内联函数和模板,而宏编译器不作任何宏参数类型检查,又极易容易出错,宏慢慢会被取代。

我们可能用的最多的就是利用宏定义常量,但我们经常被建议不要这样做,而应该使用const定义常量,因为const常量有类型,编译器会做更多的检查而减少错误。

我们也经常定义类似函数的宏,最常见的如

#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define SQUARE(a) ((a) * (a))

你可能以为SQUARE和函数一样,其实不然,比如int i = 5; SQUARE(++i); 我们期望的结果是36, 可结果是49,原因在于宏是会展开的,利用gcc -E 可以查看展开后的结果, ((++i) * (++i)) , 因此是7 × 7 == 49.

用的比较少的是#符号,它的作用是把参数变成字符串,比如

#define STR(s) #s

简单的理解就是#把后面的参数直接加上引号,因此如果是printf("%s\n", STR(5 * 5) ) 不是"25" 而是"5 * 5"。

还有一个##, 它的作用是连接两个参数,即拼凑起来,注意不是字符串连接,而是符号拼凑,比如

#define CAT(s1, s2) s1##s2

CAT(123, 456) 展开就是123456,而CAT("123", "456")得不到"123456", 编译不过去的!

宏还有与函数不同的是,不支持递归!即

#define TEST(a) ((TEST(a) + a))

TEST(5) 展开为((TEST(5) + 5))。

系统一些预定义宏也挺有用的,比如

printf("%s %s %d\n", __FILE__, __func__, __LINE__);

使用gcc -E 会展开为 printf("%s %s %d\n", "tmp.c", __func__, 5);tmp.c是源代码文件名,5是当前行号,__func__没有展开,而运行的时候会被替换成当前函数名,即输出tmp.c main 5

还有一个系统宏是 __VA_ARGS__,这个是变参列表,会自动替换成参数列表,比如

#define ERROR(format, ...) fprintf(stderr, format, __VA_ARGS__)

ERROR("errno = %d: %s\n", 404, "Not Found!");展开为fprintf(stderr, "%d:%s\n", 404, "Not Found!");

这些系统宏主要用于调试。

 

转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!
  • 无匹配
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter