查看: 551|回复: 0

[C/C++] C/C++中宏定义的使用2.1--条件编译

[复制链接]

0

技术

9

魅力

1

原创

版主

禁止访问

Rank: 7Rank: 7Rank: 7

积分
7757
人气
176
分享
52

最佳新人活跃会员

发表于 2022-11-26 14:39:26 | 显示全部楼层 |阅读模式
本帖最后由 蒟蒻 于 2022-11-26 14:43 编辑

【条件编译】
所谓条件编译,指的是通过对宏定义的判断,进行编译,有以下宏:
[C++] 纯文本查看 复制代码
#if
#elif
#else
#endif
#ifdef

【#if指令】
#if的使用方法如下:
[C] 纯文本查看 复制代码
#define 宏名 常量
#if 宏判断
    语句

注意:
必须要宏名,不能const,int,char等
例如:
[C] 纯文本查看 复制代码
#define A 10
#if A < 20
    printf("%d",a);

输入:10
别问我为什么报错,这里只是一个示例而已

这其实也可以像if语句一样,多重判断:
例如:
[C] 纯文本查看 复制代码
#include <stdio.h>

#define A 10

#if A < 0
    printf("A < 0\n");
#elif A > 0 && A < 10
    printf("A <0 && A < 10\n");
#elif A > 10 && A < 50
    printf("A > 0 && A < 50\n");
#else 
    printf("A > 50\n");

    

VS跑一下

哦吼,报错了
为什么呢?
1.没有把这个指令放在函数内
2.缺少endif
来,稍微改动亿下
[C] 纯文本查看 复制代码
#include <stdio.h>

#define A 10

int main(int argc, char** argv)
{
#if A <= 0
    printf("A <= 0\n");
#elif A <= 10
    printf("A <= 10\n");
#elif A <= 50
    printf("A <= 50\n");
#else 
    printf("A > 50\n");
#endif
}

好了,不报错了
输出:A <= 10
【ifdef】
ifdef的作用是:判断宏是否被定义
继续举栗子
[C++] 纯文本查看 复制代码
#include <stdio.h>

#define A 10

int main(int argc, char** argv)
{
#ifdef A
        printf("A已经被定义\n");
#else 
        printf("A呢?A不见了(doge\n");
#endif
}

输出:A已经被定义了
如果我们把A换成define B呢?
输出:
A呢?A不见了(doge
【if特殊形式】
我只知道一个,欢迎补充
[C] 纯文本查看 复制代码
#if __has_include(<Header>)

例如这样:
https://blog.csdn.net/qq_43546083/article/details/126410713
基于EasyX的UI库
[C] 纯文本查看 复制代码
/***************************************************************
 *                                                             *
 * UI.h                                                        *
 * UI Library for C++ Base on Easyx.                           *
 * 基于 Easyx 的 C++ UI 库                                     *
 * Version : 2022-8-14 V2                                      *
 * 版本:2022-8-14 V2                                          *
 * [url=https://easyx.cn]https://easyx.cn[/url]                                            *
 * [url=https://blog.csdn.net/qq_43546083?spm=1000.2115.3001.5343]https://blog.csdn.net/qq_43546083?spm=1000.2115.3001.5343[/url]   *
 *                                                             *
 ***************************************************************/
 
#pragma once
 
#if __has_include(<graphics.h>)
 
#include <graphics.h>
 
namespace UI {
        /**** 按钮 ****/
        class Button {
        public:
                /**** 控件左上角的x坐标 ****/
                int x = 0,
 
                /**** 控件左上角的y坐标 ****/
                y = 0;
 
                /**** 控件的宽度 ****/
                int width = 0,
 
                /**** 控件的高度 ****/
                height = 0;
 
                /**** 控件所显示的文本 ****/
                LPTSTR text = new wchar_t[1024];
 
                /**** 控件显示的文本高度 ****/
                int size = 16;
 
                /**** 控件是否可见,可见为true,否则为false ****/
                bool visible = false;
 
                /**** 构造函数,初始化控件左上角的坐标、宽度、高度、显示的文本与文本的高度(默认为16) ****/
                Button(int x, int y, int width, int height, LPCTSTR text, int size = 16) {
                        this->x = x;
                        this->y = y;
                        this->width = width;
                        this->height = height;
                        lstrcpy(this->text, text);
                        this->size = size;
                        return;
                }
 
                /**** 显示控件,成功返回true,出现异常返回false ****/
                bool show() {
                        if (visible) {
                                //当前控件可见
                                return false;
                        }
                        int temp = getbkmode();
                        setbkmode(TRANSPARENT);
                        LOGFONT* temp1 = new LOGFONT();
                        LOGFONT* temp2 = new LOGFONT();
                        gettextstyle(temp1);
                        gettextstyle(temp2);
                        temp2->lfHeight = size;
                        settextstyle(temp2);
                        if (width - textwidth(text) <= 0 || height - textheight(text) <= 0) {
                                //文字过大
                                settextstyle(temp1);
                                return false;
                        }
                        fillrectangle(x, y, x + width - 1, y + height - 1);
                        outtextxy(x + (width - textwidth(text)) / 2, y + (height - textheight(text)) / 2, text);
                        settextstyle(temp1);
                        setbkmode(temp);
                        delete temp1;
                        delete temp2;
                        visible = true;
                        return true;
                }
 
                /**** 隐藏控件 ****/
                void hide() {
                        COLORREF temp = getfillcolor();
                        setfillcolor(getbkcolor());
                        solidrectangle(x, y, x + width - 1, y + height - 1);
                        setfillcolor(temp);
                        visible = false;
                        return;
                }
 
                /**** 判断按钮是否被按下,被按下返回true,没有按下或出现异常返回false ****/
                bool click(ExMessage m) {
                        if ((x == 0 || y == 0 || width == 0 || height == 0) || !visible) {
                                //未初始化控件或当前控件不可见
                                return false;
                        }
                        return m.message == WM_LBUTTONUP && (m.x >= x && m.x <= x + width - 1) && (m.y >= y && m.y <= y + height - 1);
                }
 
                /**** 刷新插件(显示状态下) ****/
                void reload() {
                        visible = false;
                        show();
                }
 
                ~Button()
                {
                        text = nullptr;
                        delete[] text;
                }
        };
 
        /**** 文本(该控件为自动调整大小) ****/
        class Label {
        private:
                int width, height;
        public:
                /**** 控件左上角的x坐标 ****/
                int x = 0,
 
                /**** 控件左上角的y坐标 ****/
                        y = 0;
 
                /**** 控件所显示的文本 ****/
                LPTSTR text = new wchar_t[1024];
 
                /**** 控件显示的文本高度 ****/
                int size = 16;
 
                /**** 控件是否可见,可见为true,否则为false ****/
                bool visible = false;
 
                /**** 构造函数,初始化控件左上角的坐标、显示的文本与文本的高度(默认为16) ****/
                Label(int x, int y, LPCTSTR text, int size = 16) {
                        this->x = x;
                        this->y = y;
                        lstrcpy(this->text, text);
                        this->size = size;
                        width = 0;
                        height = 0;
                        return;
                }
 
                /**** 显示控件,成功返回true,出现异常返回false ****/
                bool show() {
                        if (visible) {
                                //当前控件可见
                                return false;
                        }
                        int temp = getbkmode();
                        setbkmode(TRANSPARENT);
                        LOGFONT* temp1 = new LOGFONT();
                        LOGFONT* temp2 = new LOGFONT();
                        gettextstyle(temp1);
                        gettextstyle(temp2);
                        temp2->lfHeight = size;
                        settextstyle(temp2);
                        outtextxy(x, y, text);
                        width = textwidth(text);
                        height = textheight(text);
                        settextstyle(temp1);
                        delete temp1;
                        delete temp2;
                        setbkmode(temp);
                        visible = true;
                        return true;
                }
 
                /**** 隐藏控件 ****/
                void hide() {
                        COLORREF temp = getfillcolor();
                        setfillcolor(getbkcolor());
                        solidrectangle(x, y, x + width - 1, y + height - 1);
                        setfillcolor(temp);
                        visible = false;
                        return;
                }
 
                /**** 刷新插件(显示状态下) ****/
                void reload() {
                        visible = false;
                        show();
                }
 
                ~Label()
                {
                        text = nullptr;
                        delete[] text;
                }
        };
 
        /**** 勾选框(该控件为自动大小) ****/
        class CheckBox {
        private:
                //勾选框=按钮+文本
                Button* button;
                Label* label;
 
        public:
                /**** 控件左上角的x坐标 ****/
                int x = 0,
 
                /**** 控件左上角的y坐标 ****/
                        y = 0;
 
                /**** 控件所显示的文本 ****/
                LPTSTR text = new wchar_t[1024];
 
                /**** 是否已被勾选 ****/
                bool state = false;
 
                /**** 构造函数,初始化控件左上角的坐标与显示的文本 ****/
                CheckBox(int x, int y, LPCTSTR text) {
                        this->x = x;
                        this->y = y;
                        lstrcpy(this->text, text);
                        button = new Button(x, y, 18, 18, L"");
                        label = new Label(x + 20, y, text, 18);
                        return;
                }
 
                /**** 显示控件,成功返回true,出现异常返回false ****/
                bool show() {
                        if (!button->show() || !label->show()) {
                                hide();
                                return false;
                        }
                        return true;
                }
 
                /**** 隐藏控件 ****/
                void hide() {
                        button->hide();
                        label->hide();
                        return;
                }
 
                /**** 控件是否被勾选,按下则切换效果,出现异常返回false ****/
                bool check(ExMessage m) {
                        if ((button->x == 0 || button->y == 0 || button->width == 0 || button->height == 0) || (label->x == 0 || label->y == 0) || !(button->visible && label->visible)) {
                                //未初始化控件或当前控件不可见
                                return false;
                        }
                        if (button->click(m)) {
                                state = !state;
                                state ? lstrcpy(button->text, L"√") : lstrcpy(button->text, L"");
                                reload();
                        }
                        return true;
                }
 
                /**** 刷新插件(显示状态下) ****/
                void reload() {
                        button->reload();
                        label->reload();
                }
 
                ~CheckBox()
                {
                        text = nullptr;
                        button = nullptr;
                        label = nullptr;
                        delete[] text;
                        delete button;
                        delete label;
                }
        };
 
        /**** 复选框(最多15项,该控件为自动大小) ****/
        class CheckedListBox {
        public:
                //复选框=多个勾选框
                CheckBox* checkbox[15] = { nullptr };
 
                /**** 控件左上角的x坐标 ****/
                int x = 0,
 
                /**** 控件左上角的y坐标 ****/
                        y = 0;
 
                /**** 项数 ****/
                int num = 0;
 
                /**** 构造函数,初始化控件左上角的坐标与显示的文本 ****/
                CheckedListBox(int x, int y, int num, LPCTSTR text[]) {
                        this->x = x;
                        this->y = y;
                        if (num > 15) {
                                MessageBox(0, L"项数过多!", L"UI.h", MB_OK | MB_ICONSTOP);
                                return;
                        }
                        this->num = num;
                        for (int i = 0; i < num; i++) {
                                checkbox[i] = new CheckBox(x + 5, y + 5 + i * 20, text[i]);
                        }
                }
                CheckedListBox(int num, CheckBox checkbox[]) {
                        this->x = checkbox[0].x - 5;
                        this->y = checkbox[0].y - 5;
                        if (num > 15) {
                                MessageBox(0, L"项数过多!", L"UI.h", MB_OK | MB_ICONSTOP);
                                return;
                        }
                        this->num = num;
                        for (int i = 0; i < num; i++) {
                                this->checkbox[i] = &checkbox[i];
                        }
                }
 
                /**** 显示控件,成功返回true,出现异常返回false ****/
                bool show() {
                        int maxlen = 0;
                        for (int i = 0; i < num; i++) {
                                maxlen = max(maxlen, textwidth(checkbox[i]->text));
                                if (!checkbox[i]->show()) {
                                        for (int j = 0; j < i; j++) {
                                                checkbox[j]->hide();
                                                return false;
                                        }
                                }
                        }
                        rectangle(x, y, x + maxlen + 30, y + num * 20 + 8);
                        return true;
                }
 
                /**** 隐藏控件 ****/
                void hide() {
                        for (int i = 0; i < num; i++) checkbox[i]->hide();
                }
 
                /**** 控件是否被勾选,按下则切换效果,出现异常返回false ****/
                bool check(ExMessage m) {
                        for (int i = 0; i < num; i++) {
                                if (!checkbox[i]->check(m))return false;
                        }
                        return true;
                }
 
                /**** 刷新插件(显示状态下) ****/
                void relad() {
                        for (int i = 0; i < num; i++)checkbox[i]->reload();
                        return;
                }
 
                ~CheckedListBox()
                {
                        for (int i = 0; i < num; i++) {
                                checkbox[i] = nullptr;
                                delete checkbox[i];
                        }
                }
        };
}
#else
        #error 请先安装Easyx库,下载地址:[url=https://easyx.cn]https://easyx.cn[/url]
#endif

学会了吗,好的再见[doge]

本帖被以下淘专辑推荐:

小菜鸡一枚~
Gitee主页:https://gitee.com/juruoqwq
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表