【C语言进阶】了解计算机的程序环境和预处理过程 掌握计算机预处理操作(下)

简介: 【C语言进阶】了解计算机的程序环境和预处理过程 掌握计算机预处理操作(下)

3.2 宏与函数的命名约定:

我们使用的宏定义函数,与普通函数的使用语法很相似,导致语言本身无法帮我们区分二者。所以我们通常对二者的命名进行约定:

①. 宏的名称全部大写。
②. 函数名不要全部大写。

如此就可以帮助我们区分,提升代码的可读性

4. 预处理操作符:

int main()
{
  char* p = "Hellow ""world\n";
    //*p指向两个常量字符串
  printf("Hellow world\n");
  printf("%s", p);
  return 0;
}

当我们将其编译运行发现,打印结果均为“ Hellow world”:

2dc86a4eea0d4685b37d8a80b9252765.png于是可以得知,字符串具有自动连接的特点。那么我们是不是就可以写出下面这样的代码呢?

#define PRINT(FORMAT,VALUE) printf("The value of VALUE is "FORMAT"\n",VALUE);
//可以使用宏来定义函数
//字符串"The value of VALUE is "与"\n"将会自动连接
//构造函数等价于printf("the value of VALUE is %d\n",VALUE);
#include<stdio.h>
int main()
{
  int a = 10;
  PRINT("%d", a + 3);
  return 0;
}

5d740cb3116c4256bbc2b460bd261d61.png在这段代码中,我们使用了宏来构造一个新的函数,在这个我们自己构造出来的宏函数中,其中的两个短字符串将会自动连接成为一整个长字符串,并根据我们输入的参数进行打印。于是在这个过程中,就衍生出了两个实用的预处理操作符:# 与 ##。

4.1 预处理操作符 " # ":

预处理操作符" # "的作用:将宏参数转变成其对应的字符串

这是什么意思呢?例如下面这段代码中所使用的 #N :

#define _CRT_SECURE_NO_WARNINGS 1
#define PRINT(N) printf("The value of "#N" is %d\n",N);
//N将被视为字符串"N",且字符串 N 在打印时打印的是字符串 N 的内容
#include<stdio.h>
int main()
{
  int a = 10;
  PRINT(a + 3);
  return 0;
}

在这段代码中,#N 将会被处理为字符串 N ,即" a + 3 ",于是整个宏定义函数就相当于:

printf("The value of ""a + 3"" is %d\n",VALUE);

即相当于字符串"The value of “、字符串"a + 3"与字符串” is %d\n"之间进行了自动连接,成为了一整个长字符串。

64b5c0819edd48a093c912335bf88296.png

4.2 预处理操作符 " ## ":

预处理操作符" ## "的作用:将位于其两边的符号合成为一个符号。并且,它允许宏定义从分离的文本片段中创建标识符。

#define CAT(CLASS,NAME) CLASS##NAME
//宏定义函数的作用为将符号 CLASS 与符号 NAME 合并为符号 CCLASSNAME
#include<stdio.h>
int main()
{
  int class3xiaohong = 888;
  int back = CAT(class3, xiaohong);
  //使用宏定义函数 CAT ,将符号 class3 与符号 xiaohong 合并为 class3xiaohong
  //而符号 class3xiaohong 表示的是值为 888 的 int 类型变量,故用 int 类型变量 back 接收并打印或执行其他操作
  printf("%d\n", back);
  return 0;
}

在这段代码中,通过宏定义的预处理操作符" ## “将符号” class3 “与符号” xiaohong “进行了合并,合并成了符号” class3xiaohong “,接着我们看到,在这之前我们就已经定义并初始化了 int 类型变量 class3xiaohong,于是我们就可以使用 int 类型的变量对宏定义函数所合成的符号” class3xiaohong "所表示的值进行接收了。

e51583a426e44dcd8cda5010912a87f0.png

5. 条件编译:

5.1 简述条件编译指令:

通过使用条件编译指令,我们在编译一段代码时如果要将一条(或一组)语句编译或舍弃是很方便的。例如一些调试性的代码就可以通过使用条件编译指令来实现选择性的进行编译。

#include<stdio.h>
int main()
{
  int arr[10] = { 0 };
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    arr[i] = i + 1;
    printf("%02d ", arr[i]);
#if 0
    printf("\n");
#endif
  }
  return 0;
}

在这段代码中,包含在条件编译指令 #if 与 #endif 之间的换行打印是否执行,就取决于条件编译指令的参数,此时参数为 0 ,即为假,则不进行换行打印:

667ee44f7b6d4c4b985dc0fdaf687e02.png那么我们再将参数改为1,即真:

#include<stdio.h>
int main()
{
  int arr[10] = { 0 };
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    arr[i] = i + 1;
    printf("%02d ", arr[i]);
#if 1
    printf("\n");
#endif
  }
  return 0;
}

这时条件编译指令参数为真,于是执行其中的代码进行换行打印

2f69bc6b71004eaba9534db5da3048eb.png

5.2 常见条件编译指令:

①. 单分支条件编译指令:

#if 常量表达式
    //执行操作
#endif
//或:常量表达式由预编译器求值:
#define __DEBUG__ 1
#if __DEBUG__
    //执行操作
#endif

②. 多分枝条件编译指令:

#if 常量表达式
    //执行操作
#elif 常量表达式
    //执行操作
#elif 常量表达式
    //执行操作
...
#endif

③. 判断是否被定义:

#if defined(symbol)
    //如果 symbol 被定义过,则执行操作
#endif
//或:
#if !defined(symbol)
    //如果 symbol 没有被定义过,则执行操作
#endif

④.嵌套指令:

#if defined(MAX)
    #if 1
        printf("%d\n", a > b ? a : b);
    #endif
#elif defined(MIN)
    #if 0
        printf("%d\n", a < b ? a : b);
    #endif
#endif

通过灵活的嵌套使用条件编译指令,就能实现某条或某组程序代码的选择性编译。

7.总结:

今天我们了解了计算机的程序环境和预处理过程的相关知识,学习了掌握计算机预处理操作以及对程序编译的环境、编译链接过程以及很重要的预处理指令 #define 进行了研究,并且对条件编译相关指令和宏与函数有了一定的了解和区分,希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

c3ad96b16d2e46119dd2b9357f295e3f.jpg

相关文章
|
2月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
87 5
|
2月前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
83 4
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
80 1
|
2月前
|
网络协议 物联网 数据处理
C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势
本文探讨了C语言在网络通信程序实现中的应用,介绍了网络通信的基本概念、C语言的特点及其在网络通信中的优势。文章详细讲解了使用C语言实现网络通信程序的基本步骤,包括TCP和UDP通信程序的实现,并讨论了关键技术、优化方法及未来发展趋势,旨在帮助读者掌握C语言在网络通信中的应用技巧。
66 2
|
2月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
56 1
|
11天前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
49 23
|
11天前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
42 15
|
11天前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
50 24

热门文章

最新文章