C语言进阶(预处理命令详解)

2025-07-25 20:50

本文主要是介绍C语言进阶(预处理命令详解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块...

1.宏定义

1.1不带参宏

#define  PI   3.14

变量名尽量大写

1.2带参宏

定义方式:

#defjsine  MAX(x, y)     x > y ? x : y

下面的代码运行结果为15,显然是错误的。

   #include <stdio.h>
   #define JISUAN(x, y, z)    x * y + z
   int main(void)
   {
       int a = 0;                                                      php   www.chinasem.cn                                                                                        
       a = JISUAN(1 + 2,2 * 3,3 - 1);
       printf("%d",a);
   }     

给变量带上括号,运行结果是,正确做法如下:运行结果为20。因此尽量给定义添加括号。避免计算错误。

   #include <stdio.h>
   #define JISUAN(x, y, z)    ((x) * (y) + (z))
   int main(void)
   {
       int a = 0;                                                                                                                                                 
       a = JISUAN(1 + 2,2 * 3,3 - 1);
       printf("%d",a);
   }     

带参宏和函数的区别:

带参宏函数
带参宏没有参数类型、返回值、函数类型 相关概念函数有参数类型、函数类型、返回值相关 概念
带参宏只是代码的替换,没有调用传参过 程函数有调用、传参过程
带参宏是在程序编译时展开,代码体积增 大函数是在程序运行过程中加载,代码体积 不会增大
带参宏没有传参过程,执行效率高函数有传参过程,需要调用、传参产生资 源开销
简单的代码想要封装模块,优先带参宏需要严谨的代码逻辑,多行代码,考虑使 用函数

2.头文件的包含

#include <stdio.h>
#include <string.h>
#include <math.h>
#include "head.h"

#include 包含一个文件,文件会在预处理编译时展开。

<>:在系统目录下查找该头文件。

"":在当前目录下查找该头文件,如果找不到再到系统目录下查找头文件。

2.1头文件中的内容

1.构造数据类型的定义

2.全局变量的声明

3.全局函数的声明

4.宏定义

2.2工程结构

C语言进阶(预处理命令详解)

main.c中负责主函数编写

  • 功能代码.c中主要负责功能函数的编写
  • 功能代码.h中主要负责声明功能代码.c中编写的功能函数
  • 调用函数的文件只需加对应函数的.h头文件即可使用该函数

这么说可能有些不太好理解,我们来举个例子吧:

我们先创建一个工程文件夹jisuan来进行输入两个数字的四则运算:

C语言进阶(预处理命令详解)

再在里面创建jia.c jia.h jian.c jian.h cheng.c cheng.h chu.c chu.h main.c,一个.c的功能文件必须对应一个.h的头文件声明用来方便主文件的调用!这里main.c不需要头文件。因为这里存放主函数。

C语言进阶(预处理命令详解)

创建好后分别对jia.cjian.c cheng.c chu.javascriptc函数进行编写。

  • jia.c:
   #include<stdio.h>
   float jia(float x , float y)                                                                                                                                                     
         {
             return x + y;
         }
  • jian.c:
  #include <stdio.h>
   float jian(float x , float y)
         {
             return x - y;                                                                                                                                                          
         }
  • cheng.c:
  #include<stdio.h>                                                                                                                                                                
   float cheng(float x , float y)
         {
             return x * y;
         }
  • chu.c:
   #include<stdio.h>
   extern float chu(float x , float y)                                                                                                                                              
         {
             return x / y;
         }

接下来依次编写他们的头文件:

  • jia.h
 extern float jia(float x ,float y); 

jian.h

 extern float jian(float x ,float y); 
  • cheng.h
 extern float cheng(float x ,float y); 
  • chu.h
 extern float chu(float x ,float y); 

最后我们进行主函数的编写:这里要注意一定要用#include"函数功能.h"来声明定义的变量

  • main.c:
   #include<stdio.h>
   #include"jia.h"
   #include"jian.h"
   #include"cheng.h"
   #include"chu.h"
   
   int main(void)
   {
       float r1 = 0;
      float r2 = 0;
      float r3 = 0;
      float r4 = 0;
      float a = 0;
      float b = 0;
      scanf("%f %f",&a,&b);
      r1 = jia(a,b);
      r2 = jian(a,b);
      r3 = cheng(a,b);
      r4 = chu(a,b);
      printf("jia = %f\n",r1);
      printf("jian = %f\n",r2);
      printf("cheng = %f\n",r3);
      printf("chu = %f\n",r4);
      return 0;
  }  

ok,编写工作完成,我们来对.c文件进行编译:

C语言进阶(预处理命令详解)

编译完成后就会出现一个可执行文件main

C语言进阶(预处理命令详解)

我们试着运行一下:

C语言进阶(预处理命令详解)

输入12和45,得出计算结果。

这里,我在想这不是跟我前一篇写的函数里extern外部声明一样的嘛,只不过通过#include""展开函数声明而已。但是在未来的项目中撰写每个功能代码和主函数的不是同一个人,为了方便撰写主函数的人调用,采用这样的方法是不错的选择。

3.条件编译

关键字功能描述
#if如果条件为真则编译后续代码块
#elif若前面的#if或#elif条件不成立,并且该条件成立,则编译该部分的后续代码块
#else若前面的#if和#elif都不成立,则编译该部分代码块
#endif结束一个条件编译块,必须要与#if,#ifdef,#ifndef联用
#ifdef若某个宏被定义,则使用该部分代码
#ifndef若某个宏没被定义,则使用该部分代码
#if 1
编译此部分
#elif 
不编译该部分
#else
#if 0
不编译该部分
#elif 1
编译该部分
#else
test
#if 0
不编译该部分
#elif 0
不编译该部分
#else
编译该部分
#if 1
编译该部分
#endif  结束此条件编译
#if 0
不编译该部分
#endif  结束此条件编译

#ifdef与#ifndef一般在项目测试中使用,可以在编译时http://www.chinasem.cn于外部定义或不定义某个宏,以此来调用代码。

  #include <stdio.h>
  #define JISUAN(x, y, z)    ((x) * (y) + (z))
  int main(void)
  {
      #ifdef  TEST
      printf("测试\n");
      #endif
      #ifdef  YINGYONG
      printf("应用\n");
      #endif
      return 0;
  } 

如上述代码,对其编译gcc -D TEST l.c -o l 在编译的时候在外部定义了TEST,则输出测试

C语言进阶(预处理命令详解)

如果在外部定义YINGYONG 则输出应用。

C语言进阶(预处理命令详解)

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持China编程(www.chinasem.cn)。

这篇关于C语言进阶(预处理命令详解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155485

相关文章

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D