关于#define

一、#define

1、仅仅作为标识符:

#define作为标识符时是没有参数的

2、作为宏:

#define 作为宏与它作为标识符的区别就是宏有参数而标识符没有

例如:#define MAX(X,Y) ((X)>(Y)?(X):(Y))

二、宏与函数的区别

1、宏在使用时(编译阶段)会直接被替换掉(即简单的代码复制),并且不会进行逻辑检测

2、在对代码调试时,不能进入内部调试,执行后就直接回产生值。而函数与此不同

3、宏在进行定义时不会考虑参数的类型(但这不安全)

4、宏会产生带副作用的宏参数

请分析下面这段代码:

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

#define MAX(X,Y) ((X)>(Y)?(X):(Y))

int main()
{
	int a = 10;
	int b = 20;
	int ret = MAX(a++,b++);//int ret = MAX(a++,b++) ((a++)>(b++)?(a++):(b++))
	printf("a=%d,b=%d,ret=%d\n",a,b,ret);
	system("pause");
	return 0;
}

其产生的结果为:a=11,b=22,ret=21

产生这种结果的原因就是宏被替换后产生了带副作用的参数,a被执行了一次,b被执行了两次

5、参数宏的运行速度比函数快,因为它只是简单的替换,不需要参数压栈/出栈操作

6、宏在定义时要尽量多加括号

例如:在宏定义中 #define DOUBLE(X,Y) X*Y  ,如果使用时给的参数是

(5+5,5+5),运行的结果就会出错。

7、宏可以将类型作为参数,而函数却不可以  (关于动态内存开辟)

用函数动态开辟一块空间:

int main()
{
	int *p=(int *)malloc(10*sizeof(int));
	int i=0;
	for(; i<10; i++)
	{
		p[i]=i;
	}
	for(i=0; i<10; i++)
	{
		printf("%d ",p[i]);
	}
	free(p);
	system("pause");
	return 0;
}

缺点:有可能会开辟内存失败。例如:int *p=(int *)malloc(0xffffffff);

0xffffffff  是所有内存地址编码的集合,即为所有内存,这种情况下,开辟内存就会失败,所       以在用 malloc()函数后还应该对指针 p 进行判断

	int i=0;
	int *p=(int *)malloc(10*sizeof(int));
	if(p == NULL)
	{
		printf("put of memory!\n");
		exit(1);      //结束程序
	}

而利用宏来开辟内存就会省掉这些麻烦:

#define MALLOC(COUNT,TYPE) (TYPE*)alloc(COUNT*sizeof(TYPE))
void *alloc(int sz)
{
	void *p=malloc(sz);
	if(p == NULL)
	{
		printf("out of memory!\n");
	}
	return p;
}

int main()
{
	int *p=MALLOC(10,int);
	int i=0;
	for(; i<10; i++)
	{
		p[i]=i;
	}
	for(i=0; i<10; i++)
	{
		printf("%d ",p[i]);
	}
	free(p);                //动态开辟后一定要释放这些内存,否则会发生内存泄漏
	system("pause");
	return 0;
}

开辟内存时只要传进类型就ok了

8、宏不可以递归,函数可以

#define MAX(X,Y) ((X)>(Y)?(X):(Y))
#define M 100

int main()
{
	int ret = MAX(MAX(M,20),200);    //这是嵌套使用,不是递归
	return 0;
}

9、函数只在目标文件中存在一处,比较节省空间

10、宏进行定义时,名字与参数之间不能有空格分开,但使用时可以有

时间: 2024-10-10 22:44:07

关于#define的相关文章

#define的用法

#define N 100  ok#define N 100; error#define N = 100  error   int a[N] => int a[= 100] error#define pin int*   pin a,b; error(a为int*,b为int) 2. 特殊用法 #define BEGIN {#define END } int main BEGIN    printf("haha");END 定义一个循环#define LOOP for(;;) 重

类型别名(define与typedef)

#define NEW OLD //使用预处理器的方法,为OLD定义一个新名称NEW,使用define定义的类型别名,会在预处理的过程中对NEW进行“单纯”的替换,例如: #define N 3+2 int i = N * 2; //预处理后,将会变成 int i = 3 + 2 * 2; //i 的结果将会是7 typedef typeName aliasName; //使用关键字typedef来创建别名,typedef不会创建新的类型,而只是为已知类型创建一个新名称. 两者比较: typed

OC高效率52之多用类型常量,少用#define预处理指令

// //  ViewController.m //  OC高效率52之多用类型常量,少用#define预处理指令 /**  *     1. 不要用预处理定义常量.这样定义出来的常量不含类型信息,编译器只是会在编译前据此执行查找与替换操作.即时有人重新定义了常量值,编译器也不会产生警告信息,这将导致应用程序中得常量值不一致.        2.在实现文件中使用static const 来定义"只在编译单元内可见的常量".由于此类常量不在全局符号表中,所以无需为其名称加前缀.     

【Android-tips】 Unable to execute dex: Multiple dex files define 解决方法

唔,之前已经想过今后不动android,没想到还是因为比赛的原因重操旧业.android有很多问题是由于eclipse的不完善造成的,比如今天遇到的这个问题 Unable to execute dex: Multiple dex files define [2011-10-23 16:23:29 - Dex Loader] Unable to execute dex: Multiple dex files define Lcom/myapp/R$array; [2011-10-23 16:23:

c++ typedef和#define的作用范围

typedef: 如果放在所有函数之外,它的作用域就是从它定义开始直到文件尾: 如果放在某个函数内,定义域就是从定义开始直到该函数结尾: #define: 不管是在某个函数内,还是在所有函数之外,作用域都是从定义开始直到整个文件结尾. define在同一编译单元内部,就算在不同的命名空间内,其作用范围不变.也就是从定义处一直到文件介绍. 看下面这个例子: Main.cpp /** * @file Main.cpp * @author chenjiashou([email protected])

define与typedef

#define与typedef有相似之处,但二者有本质区别 1 #define INTEGER int 和 typedef int INTEGER; 程序中INTEGER都可当做int使用,前者是预处理的宏代换,将程序中所有INTEGER先替换为int再进行编译,并没有产生新的名字:而后者是为int取了一个新的别名. 1 typerdef struct 2 { 3 int num; 4 char count; 5 }STUDENT;//STUDENT 是类型别名,注意它与直接定义结构体变量的区别

4、多用类型常量,少用#define预处理指令

摒弃: #define ANIMATION_DURATION 0.3 #define ERROR_MESSAGE @"ErrorMessage" 1)没有常量的类型信息 2)假设此指令声明在某个头文件中,那么所有引入了这个头文件的代码,都可以访问和修改ANIMATION_DURATION. 推荐: 1.私有常量 .m文件 static const NSTimeInterval kAnimationDuration = 0.3; static NSString *const kError

typedef与define宏定义用于声明新的类型之间的区别

摘自<c专家编程> typedef可以看成一种彻底的封装类型,在typedef声明类型之后不能再往里面增加其他的内容. 例子: #define peach int unsigned peach i; //没问题 typedef int banana; unsigned banana i; //错误,不能增加unsigned #define宏定义只是用于简单的替换 #define int_ptr int * int_ptr chalk, cheese; int * chalk, cheese;

Implicit super constructor Object() is undefined for default constructor. Must define an explicit c

Eclipse错误 Implicit super constructor Object() is undefined for default constructor. Must define an explicit constructor 解决方案:把Java的类库加载进去,在工程上右键选择属性->JavaBuild Path的Libraries->Add Library选择JRE System Library->点击Next->选择Execution environment并选择

-- &gt; define的用法与学习(1)

在不久之前,我一直不理解为神马大家在做题时经常用define来代替某些函数,或者用来直接定义某些极大的变量.It is not until today that I understand why it is used, and wonder at its high efficiency. 使用的原因:(1) 提高程序的运行效率 使用带参数的宏定义可完成函数调用的功能,又能减少系统开销,提高运行效率.正如C语言中所讲,函数的使用可以使程序加            模块化,便于组织,而且可重复利用,