【ThinkingInC++】47、关于宏的使用,探讨使用宏的缺点

/**
* 书本:【ThinkingInC++】
* 功能:关于宏的使用,探讨使用宏的缺点
* 时间:2014年9月11日07:50:54
* 作者:cutter_point
*/

#include"../require.h"
#include<fstream>

using namespace std;

//这里就是用BAND(x)代替后面的那一串函数
#define BAND(x) (((x)>5 && (x)<10) ? (x) : 0)

int main()
{
    ofstream out("macro.txt");
    assure(out, "macro.txt");

    for(int i=4 ; i < 11 ; ++i)
    {
        int a=i;
        out<<"a= "<<a<<endl<<'\t';
        //这里就要小心了,记住用宏代替之后的结果展开应该是这样的
        //(((++a)>5 && (++a)<10) ? (++a) : 0)这里调用了三次++a,
        //好的,代码一旦执行,问题马上就体现出来了
        out<<"BAND(++a)="<<BAND(++a)<<endl;
        out<<"\t a="<<a<<endl;
    }

    return 0;
}

/*
执行结果:
a= 4
	BAND(++a)=0
	 a=5
a= 5
	BAND(++a)=8
	 a=8
a= 6
	BAND(++a)=9
	 a=9
a= 7
	BAND(++a)=10
	 a=10
a= 8
	BAND(++a)=0
	 a=10
a= 9
	BAND(++a)=0
	 a=11
a= 10
	BAND(++a)=0
	 a=12

*/

时间: 2024-10-06 01:12:29

【ThinkingInC++】47、关于宏的使用,探讨使用宏的缺点的相关文章

【ThinkingInC++】8、说明符,探讨数据类型的大小

/** * 功能:说明符,探讨数据类型的大小 * 时间:2014年8月10日11:02:02 * 作者:cutter_point */ #include<iostream> using namespace std; int main() { char c; unsigned char cu; short int is; short iis; unsigned short int isu; unsigned short iisu; int i; unsigned int iu; long int

sas宏(2),运行中创建宏与使用宏,proc sql创建宏, scl中宏处理(暂缺)

1:在程序运行中进行宏定义 CALL routines that enable you to transfer information between an executing DATA step and the macro processor. You can use the SYMPUT routine to create a macro variable and to assign to that variable any value that is available in the DA

嵌入式C语言自我修养 12:有一种宏,叫可变参数宏

12.1 什么是可变参数宏 在上面的教程中,我们学会了变参函数的定义和使用,基本套路就是使用 va_list.va_start.va_end 等宏,去解析那些可变参数列表我们找到这些参数的存储地址后,就可以对这些参数进行处理了:要么自己动手,自己处理:要么继续调用其它函来处理. void print_num(int count, ...) { va_list args; va_start(args,count); for(int i = 0; i < count; i++) { printf(&qu

glibc 中确定宏参数个数的宏__SYSCALL_NARGS 及 可变参数宏__VA_ARGS__

读 glibc 中 关于 socket 系统调用实现的部分,然后看到了这里,写在这里做份一份笔记. #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n #define __SYSCALL_NARGS(...) \ __SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,) #define __SYSCALL_CONCAT_X(a,b) a##b #define __SYSCALL_CONCAT(a,b) __

深入探讨 内联函数和宏定义的区别

内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数. 内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定:而带参数宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患. 使用内联函数时,应注意以下问题: 1)内联函数的定义性声明应该出现在

编写一个可变参数的C函数——头文件stdarg.h中宏va_start ,va_arg和va_end的应用

我们在C语言编程中会遇到一些参数个数可变的函数,例如printf()这个函数,它的定义是这样的:int printf( const char* format, ...);它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的,例如我们可以有以下不同的调用方法:printf("%d",i);printf("%s",s);printf("the number is %d ,string is:%s", i, s);究竟如何写可变参数的

iOS中常用的宏定义

1.处理NSLog事件(开发者模式打印,发布者模式不打印) 1 2 3 4 5   #ifdef DEBUG   #define NSLog(FORMAT, ...) fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS

自己动手,丰衣足食。普通键盘实现键盘宏(Windows和Mac版)

很多高端机械键盘,支持宏定义,例如我们可以设置"D"键为"dota",这样当我们按一下宏开启键,再按一下"D"键,就等价于分别按了"d" "o" "t" "a"四个键.这时就可以把一些敲代码时常用的模板定义成键盘宏,到时候一键补全代码,既高效又装X.另外,玩游戏时想按出“下前下前拳”这样的组合技能也容易多了. 那么问题来了.. 山里来的买不起机械键盘的穷B同时又是程序

宏定义中的#,##,...,do{}while(0),__VA_ARGS__

宏定义中的#,## 1.在一个预处理器宏中的参数前面使用一个#,预处理器会把这个参数转换为一个字符数组 #define syslog(a) fprintf(stderr,"Warning: " #a"\n"); 2.简单的说,"## "是一种分隔连接方式,它的作用是先分隔,然后进行强制连接 举列 -- 试比较下述几个宏定义的区别 #define A1(name, type)  type name_##type##_type 或 #define A