C语言学习(4)—— 预处理指令和宏定义

一、预处理指令

预处理指令是以#号开头的代码行,#号必须是该行除了任何空白字符外的第一个字符。# 后是指令关键字,在关键字和 # 号之间允许存在任意个数的空白字符,整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换

指令含义
#空指令,没有任何效果
#include引入一个源文件
#define定义宏
#undef取消已定义的宏
#ifdef如果宏已经定义,则编译下面代码
#ifndef如果宏没有定义,则编译下面代码
#if如果给定条件为真,则编译下面代码
#elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
#endif结束一个#if.....#else条件编译块 
#include<stdio.h>#if _WIN64          // 如果是windows平台,则执行 #include<math.h>
#include<math.h>
#elif __linux__     // 如果是linux平台,则执行 #include<string.h>
#include<string.h>
#endifint main(){#if _WIN64double a = 2;printf("%f", pow(a, 3));    #elif __linux__     char *str = "C语言";printf("%d", strlen(str));    #endifreturn 0;
}

二、宏定义

#define 叫做宏定义命令,它是C语言预处理命令的一种,在编译之前就处理完成了,不占用内存。 

1. 不带参数的宏定义

宏定义就是用一个标识符来表示一个字符串,如果在后面的代码中出现了该标识符,那么就全部替换成指定的字符串。宏定义只是字符串替换

#define  宏名  字符串

(1)#表示这是一条预处理命令,所有的预处理命令都以#开头。

(2)宏名是标识符的一种,命名规则和变量相同,宏名为大写

(3)字符串可以是数字、表达式、if 语句、函数等,这里所说的字符串是一般意义上的字符序列,和C语言中的字符串不一样,它不需要双引号。

(4)#define在定义时没有数据类型,在参与运算时只是简单的替换。

(5)宏定义必须写在函数之外。

(6)代码中的宏名如果被引号包围,那么预处理程序不对其作宏代替

(7)可以用宏表示数据类型,宏定义表示数据类型和用 typedef 定义数据类型的区别:宏定义只是简单的字符串替换,由预处理器来处理;而 typedef 是在编译阶段由编译器处理的,它并不是简单的字符串替换,而给原有的数据类型起一个新的名字,将它作为一种新的数据类型

(6)程序中反复使用的表达式就可以使用宏定义。

#include<stdio.h>#define A  4
#define X  A
#define B  A - 2
#define C  (A - 2)
#define D  A / B * 3
#define E  A / C * 3#define UNIT unsigned int int main(){// #define在定义时没有数据类型,在参与运算时只是简单的替换。printf("X = %d \n", X);   // 4printf("D = %d \n", D);   // A / A - 2 * 3 = -5printf("E = %d \n", E);   // A / (A - 2) * 3 = 6int F = B + E;printf("F = %d \n", F);   // A - 2 + A / (A - 2) * 3 = 8// 代码中的宏名如果被引号包围,那么预处理程序不对其作宏代替printf("X \n");   // X// 可以用宏表示数据类型UNIT a = 1;      // unsigned int a = 1UNIT b = a + 2;printf("b = %d \n", b);   // b = 3return 0;
}

define可以配合#undef(取消定义)、#ifdef(如果定义了,必须与#endif配合使用)、 #ifndef(如果没有定义,必须与#endif配合使用)、#endif 来使用,可以让代码更加灵活

#include<stdio.h>#define PI 3.14    
#undef PI               //取消定义
#define PI 3.1415926    //再次定义int main(){#ifdef PIprintf("PI = %f\n", PI);    // PI = 3.1415926#endif#ifndef PIprintf("PI未定义");#endifreturn 0;
}

2. 带参数的宏定义

在宏定义中的参数称为“形参”,在宏调用中的参数称为“实参”,与函数有些类似,但是形参不用指明参数类型,实参需要指明参数类型。对带参数的宏,在展开过程中不仅要进行字符串替换,还要用实参去替换形参

#define   宏名(形参列表)   字符串              // 注意:宏名和(形参列表)之间不能有空格

带参宏调用的一般形式为:宏名(实参列表)

字符串内的形参通常要用括号括起来以避免出错

#include<stdio.h>#define MAX(a, b)  (a > b) ? a : b
#define SQ1(c)  c * c          // 字符串内的形参通常要用括号括起来以避免出错
#define SQ2(c)  (c) * (c)int main(){int x = 2; int y = 3;int max = MAX(x, y);       // int max = (x > y) ? x : y     不仅要进行字符串替换,还要用实参去替换形参printf("%d \n", max);      // 3int res1 = SQ1(x + 1);     // x + 1 * x + 1printf("%d \n", res1);     // 5  int res2 = SQ2(x + 1);     // (x + 1) * (x + 1)printf("%d \n", res2);      // 9  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/642836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你知道Mysql的架构吗?

msyql分为server曾和存储引擎层 server层包括了连接器(管理连接&#xff0c;权限验证)、查询缓存&#xff08;命中直接返回结果&#xff09;、分析器&#xff08;词法分析&#xff0c;语法分析&#xff09;、优化器&#xff08;执行计划生成&#xff0c;索引选择&#xff09;、…

java.lang.IllegalArgumentException: When allowCredentials is true

1.遇到的错误 java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a…

Vue前端规范【二】

在大多数项目中&#xff0c;这些规则被发现可以提高可读性和/或开发人员体验。如果你违反了它们&#xff0c;你的代码仍然会运行&#xff0c;但违规应该是罕见的&#xff0c;而且有充分的理由。 组件文件 每当构建系统可用于连接文件时&#xff0c;每个组件都应位于其自己的文…

vue echarts地图

下载地图文件&#xff1a; DataV.GeoAtlas地理小工具系列 范围选择器右侧行政区划范围中输入需要选择的省份或地市&#xff0c;选择自己想要的数据格式&#xff0c;这里选择了geojson格式&#xff0c;点右侧的蓝色按钮复制到浏览器地址栏中&#xff0c;打开的geojson文件内容…

gRPC-gateway使用介绍

gRPC-gateway 参考资料&#xff1a;gRPC-Gateway使用指南 服务中&#xff0c;使用了gRPC gateway&#xff08;代理&#xff09;来将外部的http请求映射为内部rpc调用。 proto文件示例&#xff1a; // 导入google/api/annotations.proto import "google/api/annotations…

Oracle 19c rac集群管理 -------- 集群启停操作过程

Oracle rac集群启停操作过程 首先查看数据库的集群的db_unique_name SQL> show parameter nameNAME TYPE VALUE ------------------------------------ ----------- --------------------------- cdb_cluster_name …

Android Dialog 显示不全的问题

前言&#xff1a;开发的时候发现一些运行到手机里的dialog显示不全&#xff0c;只显示一半左右 问了下chatgpt发现没有任何头绪&#xff0c;于是开始自己慢慢分析 显示去掉了原有的dialog的style发现问题解决了&#xff0c;但在原有基础上如何解决呢&#xff1f; 先看看xml&a…

MYSQL之索引语法与使用

索引分类 分类 含义 特点 关键字 主键索引 针对表中主键创建的索引 默认自动创建&#xff0c;只能有一个 PRIMARY 唯一索引 …

【UE】在控件蓝图中通过时间轴控制材质参数变化

效果 步骤 1. 新建一个控件蓝图和一个材质 2. 打开材质&#xff0c;设置材质域为用户界面&#xff0c;混合模式设置为“半透明” 在材质图表中添加两个参数来控制材质的颜色和不透明度 3. 对材质创建材质实例 4. 打开控件蓝图&#xff0c;在画布面板中添加一个图像控件 将刚…

DC-8靶机做题记录

靶机下载地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1jPMYoyFZXqr7sVMElHqGcw?pwdypq9 提取码&#xff1a;ypq9 参考&#xff1a; 【DC系列靶机DC8通关讲解】 https://www.bilibili.com/video/BV1R84y1H7rk/?share_sourcecopy_web&vd_source12088c392…

二、MySQL的安装和部署

2.0 描述 仅仅是一个产品&#xff0c;Oracle旗下的小型数据库。广泛应用在中小型项目中&#xff0c;特征体积小速度快整体成本低。尤其是开源&#xff0c;所以很多中小型项目为了降低成本纷纷选用MySql作为数控存储介质。 2.1 MySql的特征 底层语言使用C、C编写的。并且使用多…

指针数组与数组指针

数组指针与指针数组 动态数组 扩容&#xff1a;空间不够&#xff0c;重新申请2倍大小的连续空间&#xff0c;拷贝元素后&#xff0c;释放旧空间 动态数组区别于静态数组&#xff0c;其不具备begin(),end()操作 //动态一维数组int n 10;int *a new int[n];//可以输入n值&…

(完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子

前言 自用生信代码&#xff0c; 花费一个多月写下来的。自学R以来第一次写600多行的代码。我的文章已经发表&#xff0c;如对您的研究有帮助希望可以引用一下。文章点我 SVM-RFE 主要是借助e1071包&#xff0c; 实现mSVM-REF识别并筛选关键基因&#xff0c;没有安装的小伙伴…

在vue中不同组件通信方式

1.父子组件,通过prop 2.非父子组件,通过vuex或根vue转载器 一般是以上两种情况,但是还有一种比较特殊的情况,即孙子组件或更深层次的组件通信 parent.vue<template><div class="test"><son prop="data"></son></div>…

SpringBoot3(一)动力节点总结

目录 0、有用的新特性 一、Record 1.1、Record的介绍 1.2、Record的声明 1.3、Record的创建 0、有用的新特性 JDK8-19 新增了不少新特性&#xff0c;这里我们把实际常用的新特性&#xff0c;给大家介绍一下&#xff0c;包括以下几个方面&#xff1a; Java RecordSwich 开…

Gold-YOLO(NeurIPS 2023)论文与代码解析

paper&#xff1a;Gold-YOLO: Efficient Object Detector via Gather-and-Distribute Mechanism official implementation&#xff1a;https://github.com/huawei-noah/Efficient-Computing/tree/master/Detection/Gold-YOLO 存在的问题 在过去几年里&#xff0c;YOLO系列已经…

东南大学博士,华为上班5年,月薪达到4万4000,年终奖近10万

东南大学博士&#xff0c;华为上班5年&#xff0c;月薪达到4万4000&#xff0c;年终奖近10万 近日有华为员工爆料真实薪资&#xff0c;该网友是东南大学2018级博士&#xff0c;华为工作近5年&#xff0c;薪资达到4万4000&#xff0c;年终奖近10W。 该网友华为职场履历如下&am…

Qt6入门教程 10:菜单栏、工具栏和状态栏

目录 一.菜单栏 1.Qt Designer 1.1添加菜单和菜单项 1.2添加二级菜单 1.3给菜单和菜单项添加图标 1.4给菜单项添加功能 2.纯手写 二.工具栏 1.Qt Designer 1.1添加工具栏按钮 1.2工具栏的几个重要属性 2.纯手写 三.状态栏 1.Qt Designer 2.纯手写 用Qt Creator新…

LeetCode-题目整理【8】:罗马数字转整数、整数转罗马数字

罗马数字转整数 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#xff0c; 罗马数字 2 写做 II &#xff0c;即为两个并列的 1 。12 写做 XII &#xff0c;…

代码随想录训练营第三十期|第十四天|二叉树part01|● 理论基础● 递归遍历 ● 迭代遍历● 统一迭代

144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09; /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode…