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. 分位三个阶段:预编译、编译、汇编 ↩︎


























相关文章
|
1月前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
167 14
|
1月前
|
C语言
【C语言】全局搜索变量却找不到定义?原来是因为宏!
使用条件编译和 `extern` 来管理全局变量的定义和声明是一种有效的技术,但应谨慎使用。在可能的情况下,应该优先考虑使用局部变量、函数参数和返回值、静态变量或者更高级的封装技术(如结构体和类)来减少全局变量的使用。
45 5
|
1月前
|
编译器 C语言
【C语言】宏定义在 a.c 中定义,如何在 b.c 中使用?
通过将宏定义放在头文件 `macros.h` 中,并在多个源文件中包含该头文件,我们能够在多个文件中共享宏定义。这种方法不仅提高了代码的重用性和一致性,还简化了维护和管理工作。本文通过具体示例展示了如何定义和使用宏定义,帮助读者更好地理解和应用宏定义的机制。
63 2
|
2月前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
148 4
|
2月前
|
程序员 编译器 C语言
C语言中的预处理器指令,涵盖其基本概念、常见指令(如`#define`、`#include`、条件编译指令等)、使用技巧及注意事项
本文深入解析C语言中的预处理器指令,涵盖其基本概念、常见指令(如`#define`、`#include`、条件编译指令等)、使用技巧及注意事项,并通过实际案例分析,展示预处理器指令在代码编写与处理中的重要性和灵活性。
84 2
|
3月前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
3月前
|
编译器 C语言
C语言:typedef 和 define 有什么区别
在C语言中,`typedef`和`#define`都是用来创建标识符以简化复杂数据类型或常量的使用,但它们之间存在本质的区别。`typedef`用于定义新的数据类型别名,它保留了数据类型的特性但不分配内存。而`#define`是预处理器指令,用于定义宏替换,既可用于定义常量,也可用于简单的文本替换,但在编译前进行,过度使用可能导致代码可读性下降。正确选择使用`typedef`或`#define`可以提高代码质量和可维护性。
|
4月前
|
安全 编译器 C语言
C语言常量的定义与使用的注意点
在 C 语言中,常量是在程序运行期间值不变的量,通过字面值、`#define` 或 `const` 关键字定义。字面常量直接在代码中表示固定值,如整数 `100`、浮点数 `3.14`、字符 `'A'` 和字符串 `"Hello, World!"`;`#define` 用于定义宏,如 `#define PI 3.14159`;`const` 则定义不可变变量,如 `const int daysInWeek = 7`。常量可用于数组大小、循环边界等场景,并能提升代码的可读性和可维护性。使用时需注意作用域、类型安全和命名,避免直接使用数字(魔法数字)。
|
C语言 C++
C语言常用宏定义
01: 防止一个头文件被重复包含 #ifndef COMDEF_H #define COMDEF_H //头文件内容 #endif 02: 重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。 typedef  unsigned char      boolean;     /* Boolean value type. */ type
1409 0
|
12天前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
51 23

热门文章

最新文章