- 把宏名全部大写,函数名不要全部大写。
- 注意宏定义表示数据类型和用 typedef 定义数据说明符的区别。宏定义只是简单的字符串替换,由预处理器来处理; typedef 是在编译阶段由编译器处理的,它并不是简单的字符串替换,而给原有的数据类型起一个新的名字,将它作为一种新的数据类型。
- #define 宏名(形参列表) 字符串,这与函数的调用是不同的,函数调用时要把实参表达式的值求出来再传递给形参,而宏展开中对实参表达式不作计算,直接按照原样替换。
- 带参数的宏和函数很相似,但有本质上的区别:宏展开仅仅是字符串的替换,不会对表达式进行计算;宏在编译之前就被处理掉了,
它没有机会参与编译,也不会占用内存。
- 函数是一段可以重复使用的代码,会被编译,会给它分配内存,
每次调用函数,就是执行这块内存中的代码。
#include <stdio.h>
#include <stdlib.h>
#define SQ(y) y*y
#define PRINT printf("file:%s line:%d\n", __FILE__, __LINE__)
#define STR(s) #s
#define JOIN(a,b) a##b
void test_define_str()
{
printf("%s\n", STR(c.biancheng.net));
printf("%s\n", STR(“c.biancheng.net”));
}
void fejiw()
{
int a, sq;
printf("input a number: ");
scanf("%d", &a);
sq = SQ(a+1);
printf("sq=%d\n", sq);
}
#define CON1(a, b) a##e##b
#define CON2(a, b) a##b##00
#define ADD_TO(num, value) num##value
void test_con()
{
printf("%f\n", CON1(8.5, 2));
printf("%d\n", CON2(12, 34));
int a = ADD_TO(114, 514);
printf("%d \n", a);
}
#define PFINT printf("hello world!\n");\
printf("goodbye world!\n");
#define NUM 1,\
2,\
3
void test_huanhang()
{
PFINT
int x[] = { NUM };
printf("%d %d %d \n", x[0], x[1], x[2]);
}
#define MALLOC(num, type) \
(type *)malloc(num * sizeof(type))
void test_malloc()
{
int *b = MALLOC(10, int);
free(b);
b = NULL;
}
void test_if_()
{
#if _WIN32
system("color 0c");
printf("http://c.biancheng.net\n");
#elif __linux__
printf("\033[22;31mhttp://c.biancheng.net\n\033[22;30m");
#else
printf("http://c.biancheng.net\n");
#endif
}
#define NUMBER 10
void test_if()
{
#if NUMBER == 10 || NUM == 20
printf("NUM: %d\n", NUMBER);
#else
printf("NUM Error\n");
#endif
}
#define NUM1 10
#define NUM2 20
int test_defined()
{
#if (defined NUM1 && defined NUM2)
printf("NUM1: %d, NUM2: %d\n", NUM1, NUM2);
#else
printf("Error\n");
#endif
return 0;
}
void testerror()
{
#ifndef __cplusplus
#error 当前程序必须以C++方式编译
#endif
}
int main()
{
testerror();
return 0;
}