c语言分层理解(#define定义宏)

简介: c语言已经完结,有兴趣的可以收藏一下我的c语言专栏,感谢各位大佬支持!1.宏是什么?#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。

c语言已经完结,有兴趣的可以收藏一下我的c语言专栏,感谢各位大佬支持!

1.宏是什么?

#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义

宏(define macro)。

语法:

#define name( parament-list ) stuff

parament-list:是一个由逗号隔开的符号表。

2.宏的用法

#define SUM(x,y) ((x)+(y))
int main()
{
  int a = 10;
  int b = 20;
  int ret = SUM(a, b);
  printf("%d\n", ret);
  return 0;
}

简要说明:1宏已经被替换

3. 宏的注意事项

定义什么替换什么

来看这一例:

#define NUM(x,y) x+y
int main()
{
  int a = 2;
  int b = 3;
  printf("%d\n", NUM(a, b) * NUM(a, b));
  //结果:11
  return 0;
}

原因:num(a,b)*num(a,b) = a + b * a + b=11

4. 宏和函数的区别


属性 #define定义宏 函数
代码长度 如果多次调用,多次替换,如果是大长度宏其长度很长 函数只实现一次可以多次使用,如果多次调用,长度只有一份
执行速度 更快 函数调用和开辟都会有额外开销
操作符优先级 必须每个参数加上括号,否则操作符优先级可能会产生不可预料的后果 函数参数只在函数调用的时候求值一次,它的结果值传递给函数。表达式的求值结果更容易预测
带有副作用参数 多次调用宏会有不可预料的后果 函数参数只在传参的时候求值一次,结果更容易控制,只需关注是传值还是传址
参数类型 宏的参数和类型无关,可以使用与任何参数类型 函数参数与类型有关,类型取决于使用目的,传值,传址,还是拿一个字节数据char*
调试 不方便调试,编译期间就已经替换 可调试
递归 不可递归 可递归

宏带副作用参数

#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
int main()
{
  int x = 5;
  int y = 8;
  int z = MAX(x++, y++);
  printf("x=%d y=%d z=%d\n", x, y, z);//输出的结果是什么
  return 0;
}
//( (x++) > (y++) ? (x++):(y++) )
//输出结果:x=6,y=10,z=9

5.命名要求

  1. 宏名必须大写
  2. 函数不要全部大写

6. 条件编译

6.1 常见条件编译指令及应用场景

1.单分支

  • 编译指令:

#if 常量表达式

//…

#endif

应用场景:

int main()
{
#if 4>2
  printf("hello world!\n");
#endif
  return 0;
}
//输出hello world

2.多分支

  • 编译指令:

#if 常量表达式

//…

#elif 常量表达式

//…

#else

//…

#endif

应用场景:

int main()
{
#if 1>2
  printf("xixi\n");
#elif 4>3
  printf("haha\n");
#else 
  printf("heihei\n");
#endif
  return 0;
}
//输出结果:haha

可不能和if else选择语句混淆,多分支条件编译从上往下走,如果有一个分支成立,后面分支就不再执行;但是选择语句是从上往下走,有一个分支成立,继续查看后面分支是否成立

3.判断是否被定义

编译指令

#if 常量表达式

#ifdef symbol

//操作

#endif

#elif 常量表达式

#ifdef symbol

//操作

#endif

#endif

条件编译指令也支持嵌套,注意#endif结束本次嵌套

5.删除宏定义

  • 编译指令:

#undef

#define DEF
int main()
{
#undef DEF//删除DEF宏定义了
#ifdef DEF
  printf("hehe\n");
#endif
  return 0;
}
  1. 分位三个阶段:预编译、编译、汇编 ↩︎


























相关文章
|
5天前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
12天前
|
编译器 C语言
C语言:typedef 和 define 有什么区别
在C语言中,`typedef`和`#define`都是用来创建标识符以简化复杂数据类型或常量的使用,但它们之间存在本质的区别。`typedef`用于定义新的数据类型别名,它保留了数据类型的特性但不分配内存。而`#define`是预处理器指令,用于定义宏替换,既可用于定义常量,也可用于简单的文本替换,但在编译前进行,过度使用可能导致代码可读性下降。正确选择使用`typedef`或`#define`可以提高代码质量和可维护性。
|
1月前
|
安全 编译器 C语言
C语言常量的定义与使用的注意点
在 C 语言中,常量是在程序运行期间值不变的量,通过字面值、`#define` 或 `const` 关键字定义。字面常量直接在代码中表示固定值,如整数 `100`、浮点数 `3.14`、字符 `'A'` 和字符串 `"Hello, World!"`;`#define` 用于定义宏,如 `#define PI 3.14159`;`const` 则定义不可变变量,如 `const int daysInWeek = 7`。常量可用于数组大小、循环边界等场景,并能提升代码的可读性和可维护性。使用时需注意作用域、类型安全和命名,避免直接使用数字(魔法数字)。
|
1月前
|
存储 算法 C语言
数据结构基础详解(C语言):单链表_定义_初始化_插入_删除_查找_建立操作_纯c语言代码注释讲解
本文详细介绍了单链表的理论知识,涵盖单链表的定义、优点与缺点,并通过示例代码讲解了单链表的初始化、插入、删除、查找等核心操作。文中还具体分析了按位序插入、指定节点前后插入、按位序删除及按值查找等算法实现,并提供了尾插法和头插法建立单链表的方法,帮助读者深入理解单链表的基本原理与应用技巧。
308 6
|
2月前
|
编译器 程序员 C语言
C语言 宏
C语言 宏
37 5
|
3月前
|
Linux C语言
C语言宏IS_REACHABLE
C语言宏IS_REACHABLE
34 1
|
4月前
|
Java C语言 C++
定义C语言的int main()函数
定义C语言的int main()函数
|
4月前
|
存储 C语言
C语言中的typedef关键字:为类型定义新名称
C语言中的typedef关键字:为类型定义新名称
|
10天前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
25 3
|
1天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
17 10