美文网首页
彻底理解c的宏定义

彻底理解c的宏定义

作者: 吉凶以情迁 | 来源:发表于2019-01-07 10:43 被阅读0次

为了更方便的理解宏定义,可以直接输入g++ c文件 -E生成处理之后的源文件

#代表把#后面的变量用双引号包裹起来,也就是转换为字符串
##前面和这个参数拼接,举例···##s···代表_后面和s拼接在一起变成_s,如果没有##是无法做到的,因为他不知道你传递的是s参数。

-E                       Preprocess only; do not compile, assemble or link
  -S                       Compile only; do not assemble or link
  -c                       Compile and assemble, but do not link
  -o <file>                Place the output into <file>

举例

#define CALL(f,p) printf("Call function %s\n", _##p)
  CALL(abs,10);

结果

 printf("Call function %s\n", _10);

举例

#define CALL(f,p) printf("Call function %s\n", #p)
  CALL(abs,10);

结果
printf("Call function %s\n", "10");
错误举例

#define CALL(f,p) printf("Call function %s\n", _p)
    CALL(abs,10);

结果
printf("Call function %s\n", _p);
这里无法识别p参数10.

android日志举例

__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" "bb", "文件名宏定义", "函数名宏定义", "bb1");

//输出 [文件名宏定义:函数名宏定义]bb 这里我当时比较困惑的是为什么两个字符串在一起拼写,这明显的语法错误么,其实这可以这么写的,

所以
#define LOGV(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" fmt,"文件名宏定义", "函数名宏定义",##__VA_ARGS__)
调用LOGV("AAA") 那么第一个参数fmt就被替换了, 也就输出了[文件名:函数名] aaa
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" "bb","文件名宏定义", "函数名宏定义");
调用LOGW("AAA %s","BBB")
转换的结果是

__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" "AAA %s","文件名宏定义", "函数名宏定义","bb1");
如果删掉让我疑惑的双引号其实就是

__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s] AAA %s","文件名宏定义", "函数名宏定义","bb1");

源文件


#include <stdio.h>
#include <stdlib.h>

/*
g++ TestDefine.cpp  -save-temps 保存  ii文件
.h  C或者C++源代码头文件
.ii C++源代码(不需编译预处理)
.o  对象文件
.s  汇编语言代码
.so 动态库
<none>  标准C++系统头文件
g++ TestDefine.cpp  -E 会直接生成预处理的结果在控制台可以>写到文件
g++ file -S 生产汇编
g++  file -c 生产目标文件.o

宏定义中#s表示 把这个用字符串""包裹
##s表示这个名字和前面的某个东西链接 ,比如_##p 传递一个值为a,那么变成了_a 那么如果没有##那么是无法识别的,所以这就是他的作用.

举例  


#define CALL(f,p) printf("Call function %s\n", _##p)
  CALL(abs,10);
 printf("Call function %s\n", _10);


#define CALL(f,p) printf("Call function %s\n", #p)
  CALL(abs,10);
  printf("Call function %s\n", "10");
错误举例
#define CALL(f,p) printf("Call function %s\n", _p)
    CALL(abs,10);
    printf("Call function %s\n", _p);
这里无法识别p参数.

android日志举例 
    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" "bb", "文件名宏定义", "函数名宏定义", "bb1");
    //输出 [文件名宏定义:函数名宏定义]bb 这里我当时比较困惑的是为什么两个字符串在一起拼写,这明显的语法错误么,其实这可以这么写的,    

所以
#define LOGV(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" fmt,"文件名宏定义", "函数名宏定义",##__VA_ARGS__)
调用LOGV("AAA") 那么第一个参数fmt就被替换了, 也就输出了[文件名:函数名] aaa  
    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" "bb","文件名宏定义", "函数名宏定义");
调用LOGW("AAA %s","BBB")
转换的结果是 

    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" "AAA %s","文件名宏定义", "函数名宏定义","bb1");
如果删掉让我疑惑的双引号其实就是
    __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s] AAA %s","文件名宏定义", "函数名宏定义","bb1");

其中... 被分别替换成 ##__VA_ARGS__ 所以传递多个参数也是可以的.

*/
#define CALL(f,p) printf("Call function %s\n", _p)
#define testFunc(funcname,value) printf("%calc number :%d result %d",value,funcname) funcname(value))

   //__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" "bb",TF(), __FUNCTION__);
#define LOGV(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%s:%s]" fmt,"文件名宏定义", "函数名宏定义",##__VA_ARGS__)


int main()
{

    printf("hello ");
   // testFunc(square,5);
}

相关文章

  • 彻底理解c的宏定义

    为了更方便的理解宏定义,可以直接输入g++ c文件 -E生成处理之后的源文件 #代表把#后面的变量用双引号包裹起来...

  • C语言中的预处理器(二)

    预定义宏 ANSI C 定义了许多宏。在编程中您可以使用这些宏,但是不能直接修改这些预定义的宏。简而言之,预定义宏...

  • C语言学习:C语言宏定义

    学C语言很久了,但还是不敢用宏定义,大神喜欢用宏定义。关于宏定义你又了解多少了,下面我们说一下宏定义。 宏定义的概...

  • 精解C语言预处理命令(三)之“宏”的用法二

    关于C语言带参数的宏定义中的参数 C语言允许宏带有参数。在宏定义中的参数称为“形式参数”,在宏调用中的参数称为“实...

  • iOS开发常用的宏定义

    Objective-C常用宏/*! 字体 */ /*! 颜色宏定义 */ /*! 弱引用宏 */ /*! 输出显示...

  • 使用awk命令将C/C++ 宏定义转换为Java定义

    使用awk命令将C/C++ 宏定义转换为Java定义 项目中Hal 层的头文件的宏定义数字需要被上层应用的Java...

  • C/C++ 宏定义

    宏定义在C语言占有举足轻重的地位。底层框架自不用说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开...

  • const修饰全局变量取代宏定义

    const修饰全局变量取代宏定义 宏定义 C系程序中广泛使用宏定义,宏只是一种简单的字符串替换,根据是否带参数分为...

  • Swift 宏定义与代码标记

    Swift中的”宏” 写Objective-C的时候常常会用到各种宏定义,但是Swift中貌似没有宏的这种定义,更...

  • 编程基础

    C语言 #define定义的宏和const定义的常量有什么区别? defined定义宏的指令,程序在预处理阶段将用...

网友评论

      本文标题:彻底理解c的宏定义

      本文链接:https://www.haomeiwen.com/subject/hlwyrqtx.html