当前位置: 首页 > news >正文

C语言--预处理

文章目录

  • 一、宏定义
    •    1、宏定义
    •    2、有参宏和无参宏
    •    3、​​预定义宏​​:C语言预处理器提供了一些内置的宏,用于获取编译时的信息。
  • 二、文件包含
    •    1、标准方式:
    •    2、通用方式:
    •    3、包含保护
  • 三、条件编译
    •    1、如果标识符被定义过
    •    2、如果标识符未被定义过
    •    3、根据表达式判定
    •    4、实例:
  • 四、编译器配置
    •    1、Pragma 指令格式
    •    2、Pragma 指令常用参数
      •      #pragma message
      •      #pragma code_seg
      •      #pragma once
      •      #pragma hdrstop
      •      #pragma resource
      •      #pragma warning
      •      #pragma disable
      •      #pragma data_seg

  C语言预处理是C语言编译过程中的一个重要阶段,它在编译器对源代码进行编译之前,由预处理器对源代码进行一系列文本处理操作。预处理指令以井号(#)开头,它们不是C语言的语句,因此不需要以分号(;)结尾。

一、宏定义

   宏定义的作用就是在程序中某段代码的一个别名,宏定义主要是为程序调试、移植等提供便利是一个非常实用的功能。

   1、宏定义

     所有的宏命令行都以符号“#define”开头,并且结尾不用分号,
       例: #define PI 3.14
     宏定义的作用是在编译处理时,将源程序中所有标识替换成语名序列,宏定义分为有参宏和无参宏。

     需要注意的是,宏名一般用大写字母,以便于与变量名的区别,在编译与处理时,宏名与字符串进行替换时,不做语法检查,只是简单的字符替换,只有在编译时才对已展开的宏名的源程序进行语法检查,宏名的有效范围是从定义位置到文件结束,如果需要终止红定义的作用域可以用 “#undef”命令,
     例如:
       #define PI 3.14
       ……
       #undef PI

   2、有参宏和无参宏

     无参宏指的是执行单一的替换功能的宏定义,在使用无参红时要注意以下两个问题,
       1.宏定义时可以引用已经定义的宏名如以下所示:
         #define R 2.0
         #define PI 3.14
         #define L 2RPI
       2.对程序中用双引号括起来的字符的字符串内的字符,不进行宏定义的替换操作。
     有参宏可以让我们在宏定义时,还可以带参数扩大宏的应用范围,有参宏的格式:
       #define 标识符(参数表) 字符串
       它的作用是在编译预处理时,将原程序中所有的标识符替换成字符串,并且将字符串中的参数用实际使用的参数替换,
       例如:
         #define S(a,b) (a*b)/2
     需要注意的是,在宏定义时,宏名和参数之间不能有空格,否则空格后面的所有字符序列都作为替换的字符串,带参数的宏展开时,只做简单的字符和参数替换,不进行任何计算操作,所以一般在宏定义时字符串中的形式参数外面加一个小括号
     例如:
       #define L( r ) 2*PI*r
       如果输入 L(2+3) 则编译后变为 2*3.14*2+3 不是2*3.14*5
     解决方法:
       #define L( r ) 2*PI*( r )

   3、​​预定义宏​​:C语言预处理器提供了一些内置的宏,用于获取编译时的信息。

    宏        描述
    __FILE__    当前源文件名(字符串)
    __LINE__    当前行号(整数)
    __DATE__    编译日期(字符串)
    __TIME__    编译时间(字符串)
    __STDC__    如果编译器遵循ANSI C标准,则定义为1。

二、文件包含

   文件包含的功能是将指定的文件内容嵌入到一个原文件中,文件包含共有以下两种格式:

   1、标准方式:

     只按照标准方式在C语言编译器的C函数库头文件中查找要包含的文件。
     #include <> 一般用于包含系统头文件,诸如 stdlib.h 、stdio.h 、iostream等;
     #include <xxxx.x>

   2、通用方式:

     先在原文件所在的目录中查找要包含的文件,若未能找到,则在按照标准方式查找。
     #include " " 一般用于包含自定义头文件,如test.h、declare.h等
     #include “xxxx.x”

   3、包含保护

     为了避免头文件被重复包含,通常会在头文件中使用​​包含保护:

			#ifndef MY_HEADER_H#define MY_HEADER_H// 头文件内容#endif

三、条件编译

   #ifdef #ifndef #if #else #endif
   条件编译一般用于某种条件判断是否要编译某一段代码,常用的格式如下:

   1、如果标识符被定义过

			#ifdef 标识符/*程序段1*/#else/*程序段2*/#endif 

   2、如果标识符未被定义过

			#ifndef 标识符/*程序段1*/#else/*程序段2*/#endif

   3、根据表达式判定

			#if 表达式/*程序段1*/#else/*程序段2*/#endif 

   4、实例:

			#include <stdlib.h>#include <stdio.h>#define ABC 123456int main(){#ifdef ABC printf("定义了ABC !\n");#elseprintf(L"未定义ABC !\n");#endif#ifndef  CBAprintf("未定义CBA!\n");#endifsystem("pause");return 0;}

四、编译器配置

   #Pragma 指令的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。
   #pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。

   1、Pragma 指令格式

      格式一般为:
         #pragma Para //其中Para 为参数。

   2、Pragma 指令常用参数

     #pragma message

         Message 参数能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。
         其使用方法为:
            #pragma message(“消息文本”)
         当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。

     #pragma code_seg

         设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。
         格式:
            #pragma code_seg([“section-name”[,“section-class”]])

     #pragma once

         只要在头文件的最开始加入这条指令就能够保证头文件被编译一次。

     #pragma hdrstop

         #pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译。

     #pragma resource

         #pragma resource ".dfm"表示把.dfm文件中的资源加入工程。*.dfm中包括窗体外观的定义。

     #pragma warning

         #pragma warning(disable:450734;once:4385;error:164)
         等价于:
           #pragma warning(disable:450734)//不显示4507和34号警告信息
           #pragma warning(once:4385)//4385号警告信息仅报告一次
           #pragma warning(error:164)//把164号警告信息作为一个错误。

     #pragma disable

         在函数前声明,只对一个函数有效。该函数调用过程中将不可被中断。一般在C51中使用较多。

     #pragma data_seg

         用#pragma data_seg建立一个新的数据段并定义共享数据,其具体格式为:
            #pragma data_seg(“shareddata”)
           HWND sharedwnd=NULL;//共享数据
           #pragma data_seg()

         1、#pragma data_seg()一般用于DLL中。也就是说,在DLL中定义一个共享的有名字的数据段。
        最关键的是:这个数据段中的全局变量可以被多个进程共享,否则多个进程之间无法共享DLL中的全局变量。
         2、共享数据必须初始化,否则微软编译器会把没有初始化的数据放到.BSS段中,从而导致多个进程之间的共享行为失败。

http://www.dtcms.com/a/483503.html

相关文章:

  • 电子商务网站建设核心是河南省城乡建设厅网站首页
  • 个人网站备案名称咋制作网站
  • 做网站需要考虑什么金融网站开发文档
  • 白细胞偏高:揪出原因,科学应对
  • 【开题答辩过程】以《助农电商信息管理系统的设计与实现》为例,不会开题答辩的可以进来看看
  • HT4822立体声耳机放大器:打造高品质音频
  • 使用NVIDIA TAO 6和DeepStream 8构建实时视觉检测管道
  • Java并发机制的底层实现原理:从CPU到JVM的全面解析
  • 判断web代理服务未生效以及测试服务是否生效
  • 视觉检测设备-AI视觉质量检测方案提升效率
  • 原生多模态AI架构:统一训练与跨模态推理的系统实现与性能优化
  • 荣耀手机商城官方网站入口网站制作公司深圳
  • 网站内容运营免费建网站的服务器
  • Spring Boot 集成免费的 EdgeTTS 实现文本转语音
  • Hexo + Butterfly 博客添加 Live2D 看板娘指南
  • 陕西渭南富平建设局网站个人网站 数据库如何上传到空间
  • 亚马逊用什么网站上传做新品好电子工程信息建设网
  • Flutter---默认程序(计数器)
  • 网站建设网站管理网站推广推广
  • Java 23种设计模式的详细解析
  • k8s lease使用案例
  • 武威 网站建设更改网站标题
  • idea中设置快捷键风格
  • 百刀打造ChatGPT:nanochat极简LLM全栈实现深度解析
  • 建立网站该怎样做有没有免费制作视频的软件
  • IDEA自带的Maven安装位置
  • mui做浏览器网站跳转网站建设加盟培训
  • 互联网三网合一网站建设erp系统软件免费版
  • 英文互动网站建设最好最值得做的调查网站
  • 做网站创意微信域名防封跳转系统