首页 > 其他分享 >【C语言】宏定义详解---老公出轨版 (づ◡﹏◡)づ

【C语言】宏定义详解---老公出轨版 (づ◡﹏◡)づ

时间:2024-08-26 15:50:36浏览次数:15  
标签:出轨 示例 int C语言 --- pragma printf include define

LuckiBit

目录

C语言宏定义详解

在C语言中,宏定义是一种强大的预处理器功能,用于在编译之前对代码进行替换和条件编译。宏定义通过预处理器指令进行定义和使用,能够使代码更加灵活和可维护。本文将对C语言中的宏定义进行全面的讲解,包括各种相关的预处理器指令及其用法。

1. 宏定义关键词总览

关键词用途
#define定义宏(常量宏或函数宏)。
#undef取消(取消定义)一个先前定义的宏。
#ifdef检查某个宏是否已定义。
#ifndef检查某个宏是否未定义。
#if根据宏或表达式的值决定是否包含代码。
#else#if#ifdef#ifndef配合使用,提供条件不满足时的替代代码。
#elif提供额外的条件检查,类似于else if
#endif结束#if#ifdef#ifndef#elif块。
#include在当前文件中包含另一个文件,通常用于头文件的引入。
#error在预处理阶段生成错误信息并终止编译。
#pragma向编译器提供特定的指令或设置,依赖于编译器实现。
#line改变当前文件的行号和文件名,通常用于调试。
#将宏参数转换为字符串,称为字符串化操作符。
##在宏定义中连接两个标识符,称为标识符连接操作符。

2. #define

#define 指令用于定义宏,可以是常量宏或函数宏。常量宏用于定义常量值,而函数宏用于定义带参数的代码片段。

语法

#define MACRO_NAME replacement_text

示例

#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))

示例代码

#include <stdio.h>

#define PI 3.14159
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main() {
    printf("PI: %f\n", PI);
    printf("Max of 10 and 20: %d\n", MAX(10, 20));
    return 0;
}

输出

PI: 3.141590
Max of 10 and 20: 20

3. #undef

#undef 指令用于取消之前定义的宏,使其在后续代码中不再有效。

语法

#undef MACRO_NAME

示例

#include <stdio.h>

#define TEMP 100
#undef TEMP

int main() {
    // TEMP is no longer defined, so this will cause a compile error
    // printf("TEMP: %d\n", TEMP);
    return 0;
}

取消宏定义后,使用 TEMP 将导致编译错误,因为它不再被定义。

4. #ifdef

#ifdef 指令用于检查某个宏是否已定义。如果宏已定义,则编译相关的代码块。

语法

#ifdef MACRO_NAME
    // Code to be compiled if MACRO_NAME is defined
#endif

示例

#include <stdio.h>

#define DEBUG

#ifdef DEBUG
    printf("Debug mode is on\n");
#endif

int main() {
    return 0;
}

输出

Debug mode is on

5. #ifndef

#ifndef 指令用于检查某个宏是否未定义。如果宏未定义,则编译相关的代码块。

语法

#ifndef MACRO_NAME
    // Code to be compiled if MACRO_NAME is not defined
#endif

示例

#include <stdio.h>

#ifndef VERSION
#define VERSION 1
#endif

int main() {
    printf("Version: %d\n", VERSION);
    return 0;
}

输出

Version: 1

6. #if

#if 指令用于根据宏或表达式的值决定是否编译某些代码。它允许使用常量表达式进行条件判断。

语法

#if CONDITION
    // Code to be compiled if CONDITION is true
#endif

示例

#include <stdio.h>

#define VERSION 2

#if VERSION >= 2
    printf("Version is 2 or higher\n");
#endif

int main() {
    return 0;
}

输出

Version is 2 or higher

7. #else

#else 指令用于在 #if#ifdef#ifndef 等条件编译指令中提供条件不满足时的替代代码。

语法

#if CONDITION
    // Code to be compiled if CONDITION is true
#else
    // Code to be compiled if CONDITION is false
#endif

示例

#include <stdio.h>

#define DEBUG

#ifdef DEBUG
    printf("Debug mode is on\n");
#else
    printf("Debug mode is off\n");
#endif

int main() {
    return 0;
}

输出

Debug mode is on

8. #elif

#elif 指令用于提供额外的条件检查,类似于 else if,用于在 #if#ifdef#ifndef 中增加更多的条件。

语法

#if CONDITION1
    // Code to be compiled if CONDITION1 is true
#elif CONDITION2
    // Code to be compiled if CONDITION2 is true
#endif

示例

#include <stdio.h>

#define VERSION 2

#if VERSION == 1
    printf("Version 1\n");
#elif VERSION == 2
    printf("Version 2\n");
#else
    printf("Other version\n");
#endif

int main() {
    return 0;
}

输出

Version 2

9. #endif

#endif 指令用于结束一个由 #if#ifdef#ifndef#elif 等开始的条件编译块。

语法

#if CONDITION
    // Code to be compiled if CONDITION is true
#endif

示例

#include <stdio.h>

#define VERSION 1

#if defined(VERSION)
    printf("Version is defined\n");
#endif

int main() {
    return 0;
}

输出

Version is defined

10. #include

#include 指令用于在当前文件中包含另一个文件,通常用于引入头文件。包括文件可以是系统文件或自定义文件。

语法

#include <filename>    // For system files
#include "filename"    // For user-defined files

示例

#include <stdio.h>
#include "myheader.h"

int main() {
    return 0;
}

11. #error

#error 指令用于在预处理阶段生成错误信息并终止编译。它可以用于在编译过程中检测特定的条件并报告错误。

语法

#error error_message

示例

#include <stdio.h>

#ifndef VERSION
#error "VERSION is not defined"
#endif

int main() {
    return 0;
}

输出

VERSION is not defined

12. #pragma

#pragma 指令用于向编译器提供特定的指令或设置。#pragma 的具体行为依赖于编译器实现。以下是几个常见的 #pragma 示例:

12.1 #pragma once

用于防止头文件被多次包含。它确保头文件只会被处理一次。

示例

// myheader.h
#pragma once

void myFunction();

在多个源文件中包含 myheader.h 时,#pragma once 确保它只被处理一次。

12.2 #pragma pack

用于设置结构体对齐方式,控制结构体在内存中的对齐方式。

示例

#include <stdio.h>

#pragma pack(push, 1)
typedef struct {
    char c;
    int i;
} MyStruct;
#pragma pack(pop)

int main() {
    MyStruct ms;
    printf("Size of MyStruct: %zu\n", sizeof(ms));
    return 0;
}

在这个示例中,#pragma pack(push, 1) 指定了结构体 MyStruct 以1字节对齐,这会使 MyStruct 结构体的大小为5字节(1字节的 char 和4字节的 int)。#pragma pack(pop) 恢复之前的对齐设置。

输出

Size of MyStruct: 5

12.3 #pragma warning

用于控制编译器的警告信息,可以启用、禁用或设置警告级别。这些指令依赖于编译器,下面以 MSVC 编译器为例。

示例

#include <stdio.h>

#pragma warning(push)
#pragma warning(disable: 4996)  // 禁用特定警告
#include <stdlib.h>
#pragma warning(pop)

int main() {
    char str[10];
    sprintf(str, "Hello");
    printf("%s\n", str);
    return 0;
}

在这个示例中,#pragma warning(disable: 4996) 用于禁用有关不安全函数的警告,例如 sprintf 函数。#pragma warning(push)#pragma warning(pop) 保存和恢复警告状态。

输出

Hello

12.4 #pragma GCC

对于 GCC 编译器,#pragma GCC 允许控制一些 GCC 特性和行为。例如,可以禁用特定的优化警告。

示例

#include <stdio.h>

#pragma GCC push_options
#pragma GCC optimize ("O0")  // 禁用优化
void foo() {
    printf("Function foo()\n");
}
#pragma GCC pop_options

int main() {
    foo();
    return 0;
}

在这个示例中,#pragma GCC optimize ("O0") 禁用优化,这样 foo 函数不会被优化掉,可以用于调试。

输出

Function foo()

13. #line

#line 指令用于改变当前文件的行号和文件名,通常用于调试,帮助定位编译器生成的错误。

语法

#line line_number "file_name"

示例

#include <stdio.h>

#line 100 "newfile.c"
int main() {
    printf("Current line: %d\n", __LINE__);
    return 0;
}

在这个示例中,#line 100 "newfile.c" 将当前行号设置为100,并将文件名设置为 newfile.c__LINE__ 预定义宏会返回设置的行号。

输出

Current line: 100

14. 字符串化和标识符连接

14.1 字符串化(#

字符串化操作符将宏参数转换为字符串。

语法

#define STRINGIFY(x) #x

示例

#include <stdio.h>

#define STRINGIFY(x) #x

int main() {
    printf("STRINGIFY(Hello): %s\n", STRINGIFY(Hello));
    return 0;
}

输出

STRINGIFY(Hello): Hello

14.2 标识符连接(##

标识符连接操作符将两个标识符连接成一个标识符。

语法

#define CONCAT(a, b) a##b

示例

#include <stdio.h>

#define CONCAT(a, b) a##b

int main() {
    int ab = 10;
    printf("Value of ab: %d\n", CONCAT(a, b));
    return 0;
}

输出

Value of ab: 10

15. 总结

C语言中的宏定义是一种强大的预处理器功能,用于在编译之前对代码进行替换和条件编译。通过使用 #define#undef#ifdef#ifndef#if#else#elif#endif#include#error#pragma 和其他指令,可以灵活地控制代码的编译过程。理解这些宏定义的用法可以帮助开发人员编写更加高效和可维护的代码。

16. 结束语

  1. 本节内容已经全部介绍完毕,希望通过这篇文章,大家对C语言宏定义有了更深入的理解和认识。
  2. 感谢各位的阅读和支持,如果觉得这篇文章对你有帮助,请不要吝惜你的点赞和评论,这对我们非常重要。再次感谢大家的关注和支持点我关注❤️

相关文章:

标签:出轨,示例,int,C语言,---,pragma,printf,include,define
From: https://blog.csdn.net/EleganceJiaBao/article/details/141565347

相关文章

  • C#进阶-快速了解IOC控制反转及相关框架的使用
    目录一、了解IOC1、概念2、生命周期二、IOC服务示例1、定义服务接口 2、实现服务三、扩展-CommunityToolkit.Mvvm工具包Messenger信使方式一(收发消息)方式二(收发消息)方式三(请求消息)一、了解IOCIOC,即控制反转(InversionofControl),它通过将对象的创建和管理责任从......
  • jenkins安装及自动化部署-docker部署
    一、安装1.创建jenkins工作目录mkdir/home/chanfi/docker/jenkins2.下载JDK#进入工作目录下cd/home/chanfi/docker/jenkins#创建JDK目录mkdirjavacdjava#下载jdk(或到官网中下载:https://www.oracle.com/java/technologies/downloads/?er=221886)wgethttps://d......
  • 【文档智能 & RAG】浅看开源的同质化的文档解析框架-Docling
    前言RAG的兴起,越来越多的人开始关注文档结构化解析的效果,这个赛道变得非常的同质化。关于文档智能解析过程中的每个技术环节的技术点,前期文章详细介绍了很多内容:下面我们简单的看看Docling这个PDF文档解析框架里面都有什么技术。方法布局分析模型首先,Docling使用一......
  • 【qemu+libvirt+virt-manager源码安装】
    0.前言编译需要用到高版本python(>=3.8),参考附录查看教程,我使用的python3.11,所有后文的python3都是它的链接。1.源码安装qemu1.1源码安装aptinstallgtk+-3.0 #后面qemu编译依赖用的到wgethttps://download.qemu.org/qemu-9.1.0-rc2.tar.xztarxvJfqemu-9.1.0-......
  • CSS处理font-weight不生效问题
    如何解决Android系统中文字体字重问题翻找了几天资料,发现NotoSansSC字体能支持中文/数字/英文字体100,300,400,500,700,900的字重,具体如下图所示:<linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Noto+Sans+SC:300,400,500,600,700"></link>.t......
  • MySQL-基础篇
    MySQL概述1、数据库相关概念主流的关系型数据库:总结1)数据库:数据存储的仓库2)数据库管理系统:操纵和管理数据库的大型软件3)SQL:操作关系型数据库的编程语言,是一套标准2、MySQL数据库版本MySQL官方提供了两种不同的版本:社区版(MySOLCommunityServer)=>免费,MySQL......
  • 【MATLAB源码-第149期】基于MATLAB的2ASK,2FSK,2PSK,2DPSK等相干解调仿真,输出各节点波
    操作环境:MATLAB2022a1、算法描述2ASK(二进制幅移键控)、2FSK(二进制频移键控)、2PSK(二进制相移键控)和2DPSK(二进制差分相移键控)是数字调制技术中的基本调制方式,它们在无线通信、数据传输等领域有着广泛的应用。相干解调是这些调制方式中一个重要的解调技术,它要求接收端的本地振......
  • 【链栈的实现】--------本质为不带头结点的 头插法建立起来的单链表
    1.链栈的基本属性与特征:链栈是运算受限的单链表,只能在链表头部进行操作2.链栈的相关基础操作汇总初始化操作:操作结果:构造一个空栈S。InitStack(LinkStack*s)判定S是否为空栈:初始条件:栈S已存在操作结果:若栈S为空栈,则返回TRUE,否则FALSE.StackEmpty(LinkStack......
  • 22-lenet网络
    importtorchimporttorch.nnasnnfromd2limporttorchasd2lnet=nn.Sequential(nn.Conv2d(1,6,kernel_size=(5,5),padding=2),nn.Sigmoid(),nn.AvgPool2d(kernel_size=(2,2),stride=2),nn.C......
  • v-bind指令与class类和style的内联样式的绑定
    1.v-bind指令1.v-bind的认知与用法我们先创建一个新的页面去除掉一些元素保留剩下的元素然后对其添加一些属性和值创建好了之后我们可以来在页面上显示一个图片用我们的image组件找到我们的本地图片的位置或者网络图片的url放入我们的src里面。在src里面用到了我们的图片......