1.定义
预处理命令是c++统一规定的,但是它不是c++语言本身的组成部分,不能直接对他们进行编译
2.预处理的分类
2.1 宏定义 #typeof
#typeof IS_DEBUG true
2.2 文件包含 #include
#include<android/log.h> #include<string>
是指一个源文件可以将另外一个源文件的全部内容包含进来,也就是将另外的文件包含到本文件之中
#include <文件名> 在系统目录中寻找
#include "文件名" 现在指定目录去寻找,然后再去系统目录找,如果没有给出绝对路径,则现在用户当 前目录去寻找
C的标准库加.h,c++标准库可以不加.h
2.3.条件编译 #ifndefine
#ifndef LOG_TAG #define LOG_TAG "JNI" #endif #ifndef IS_DEBUG #define IS_DEBUG true #endif
#ifndef标识符 字符串
#define 标识符 字符串
#define 命令定义参数的宏定义
#define 宏名(参数表) 字符串
以上两种用法由于常量的定义以及增加的内置函数更加方便,所以现在#define命令多见于条件编译中
#ifndef
#ifdef 标识符 当指定的标识符已经被#define命令定义过,
程序段1 则只编译程序段1
#else 否则
程序段2 编译程序段2
#endif 限定#ifdef命令的范围
#if 表达式 表达式为真时
程序段1 编译程序段1
#else 否则
程序段2 编译程序段2
#endif 结束#if命令
2.4一个完整的例子如下:
#include "android/log.h" #ifndef LOG_TAG #define LOG_TAG "JNI" #endif #ifndef IS_DEBUG #define IS_DEBUG true #endif #define LOG_NOOP (void) 0 //__FILE__ 输出文件名 //__LINE__ 输出行数 // __PRETTY_FUNCTION__ 输出方法名 //可以按需选取 %s %u %s 分别与之对应 #define LOG_PRINT(level, fmt, ...) __android_log_print(level,LOG_TAG,"(%s:%u) %s: " >fmt,__FILE__,__LINE__,__PRETTY_FUNCTION__,##__VA_ARGS__) //通过IS_DEBUG来控制是否输出日志 #if IS_DEBUG #define LOGI(fmt, ...) LOG_PRINT(ANDROID_LOG_INFO,fmt,##__VA_ARGS__) #else #define LOGI(...) LOG_NOOP #endif #if IS_DEBUG #define LOGW(fmt, ...) LOG_PRINT(ANDROID_LOG_WARN,fmt ,##__VA_ARGS__) #else #define LOGW(...) LOG_NOOP #endif #if IS_DEBUG #define LOGD(fmt, ...) LOG_PRINT(ANDROID_LOG_DEBUG,fmt ,##__VA_ARGS__) #else #define LOGD(...) LOG_NOOP #endif #if IS_DEBUG #define LOGE(fmt, ...) LOG_PRINT(ANDROID_LOG_ERROR,fmt ,##__VA_ARGS__) #else #define LOGE(...) LOG_NOOP #endif #if IS_DEBUG #define LOGF(fmt, ...) LOG_PRINT(ANDROID_LOG_FATAL,fmt ,##__VA_ARGS__) #else #define LOGF(...) LOG_NOOP #endif
3.常用预定义宏
__LINE__: 当前源文件的行号,整数
__FILE__: 当前源文件名,char 字符串,使用 /FC 选项产生全路径
__DATE__: 当前编译日期,char 字符串,格式 月 日 年
__TIME__: 当前编译时间,char 字符串,格式 时:分:秒
__STDC__: 整数 1,表示兼容 ANSI/ISO C 标准,配合 #if 使用
__TIMESTAMP__: 最后一次修改当前文件的时间戳,char 字符串,格式 星期 月份 日期 时:分:秒 年