• c++-基本计算器的灵活可扩展实现


    实现一个可灵活扩充功能的计算器, 面向对象设计
    可以灵活添加绝大部分运算操作符
    并附带ui 界面方便使用

    集成库

    编译

    g++ -fPIC -shared main.cpp -std=c++17  -o cal.so 
    
    • 1

    计算器可视化

    python UI

    界面

    在这里插入图片描述

    功能拓展

    比如支持 & bit_and 运算 比如 10 & 5

    只需要修改如下

    增加新的计算函数

    class BitAndOperator : public Operator {
    public:
        BitAndOperator() : Operator(2) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return buffer[0] & buffer[1];
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    增加新的优先级

    int priority(char op) {
            switch (op) {
                case '(':
                    return 100000;
                case '!':
                case '~':
                case 'z':  // z --> 一元+
                case 'y':  // y --> 一元-
                case 's':
                    return 10000;
                case '*':
                case '/':
                case '%':
                    return 1000;
                case '+':
                case '-':
                    return 100;
                case '&':
                case '^':
                    return 50;
                case ')':
                    return -1;
                default:
                    return 0;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    注册操作

    unordered_map<char, Operator*> RPN::opfunc_map {
            {'z', new UnaryAddOperator},
            {'y', new UnarySubOperator},
            {'+', new AddOperator},
            {'-', new SubOperator},
            {'*', new MultiplyOpeator},
            {'/', new DivideOperator},
            {'s', new SinOperator},
            {'&', new BitAndOperator},
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    计算器c++源码

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    /**** 基本计算器
     * 支持运算符
     * 一元运算符    特殊处理 - -> _     +直接删去
     * 二元运算符 + - * /
     * 特殊() [] {}
     * 扩充一元运算符
     * sin -> s
     * cos -> c
     * tan -> t
     *
     * 扩充二元运算符 |(二进制与) &(二进制或) ^(二进制异或)
     */
    
    using OPTYPE = double;
    int err_no = 0;
    
    class Operator {
    private:
        int cnt = 2;
    
        virtual OPTYPE cal(OPTYPE *buffer) = 0;
    
    public:
        explicit Operator(int cnt) : cnt(cnt) {}
    
        virtual OPTYPE cal(stack<OPTYPE> &st) {
            if (st.size() < cnt) {
                cout << "st.size() < cnt";
                err_no = -1;
                return errno;
            }
            OPTYPE buffer[cnt];
            int idx = cnt;
            while (idx-- > 0) {
                buffer[idx] = st.top();
                st.pop();
            }
            return cal(buffer);
        }
    };
    
    class UnaryAddOperator : public Operator {
    public:
        explicit UnaryAddOperator() : Operator(1) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return buffer[0];
        }
    };
    
    class UnarySubOperator : public Operator {
    public:
        UnarySubOperator() : Operator(1) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return -buffer[0];
        }
    };
    
    class AddOperator : public Operator {
    public:
        explicit AddOperator() : Operator(2) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return buffer[0] + buffer[1];
        }
    };
    
    class SubOperator : public Operator {
    public:
        explicit SubOperator() : Operator(2) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return buffer[0] - buffer[1];
        }
    };
    
    class MultiplyOpeator : public Operator {
    public:
        MultiplyOpeator() : Operator(2) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return buffer[0] * buffer[1];
        }
    };
    
    class DivideOperator : public Operator {
    public:
        DivideOperator() : Operator(2) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return buffer[0] / buffer[1];
        }
    };
    
    class SinOperator : public Operator {
    public:
        SinOperator() : Operator(1) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return sin(buffer[0]);
        }
    };
    
    class CosOperator : public Operator {
    public:
        CosOperator() : Operator(1) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return cos(buffer[0]);
        }
    };
    
    class TanOperator : public Operator {
    public:
        TanOperator() : Operator(1) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return tan(buffer[0]);
        }
    };
    
    class ModOperator : public Operator {
    public:
        ModOperator() : Operator(2) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            return (long long) buffer[0] % (long long) buffer[1];
        }
    };
    
    class BitAndOperator : public Operator {
    public:
        BitAndOperator() : Operator(2) {}
    
    private:
        OPTYPE cal(OPTYPE *buffer) override {
            if constexpr(sizeof(OPTYPE) == 8) {
                return (long long) buffer[0] & (long long) buffer[1];
            }
            return (int) buffer[0] & (int) buffer[1];
        }
    };
    
    class RPN {
    private:
        static unordered_map<string, char> opname_map;
    
        static unordered_set<char> canMiss;
    
    
        string rpn;
        string result;
        static unordered_map<char, Operator *> opfunc_map;
    
        // 左结合运算符 取正
        // 右结合运算符取负, 目前只支持sin cos tan
        int priority(char op) {
            switch (op) {
                case '(':
                    return 100000;
                case '!':
                case '~':
                case 'z':  // z --> 一元+
                case 'y':  // y --> 一元-
                    return 10000;
                case '*':
                case '/':
                case '%':
                    return 1000;
                case '+':
                case '-':
                    return 100;
                case '&':
                case '^':
                    return 50;
                case ')':
                    return 0;
                case 's':
                case 't':
                case 'c':
                    return -10000;
                default:
                    return 0;
            }
        }
    
        // 特殊处理
        string formatSpecialFix(const string s) {
            string ans;
            bool has_num = false;
            for (int i = 0; i < s.size(); i++) {
                switch (s[i]) {
                    case '+':
                    case '-': {
                        bool unary = false;
                        if (i == 0) {
                            unary = true;
                        } else {
                            int j = i;
                            while (j - 1 >= 0 && canMiss.count(s[j - 1])) {
                                j--;
                            }
                            if (j - 1 >= 0 && s[j - 1] == '(') {
                                unary = true;
                            }
                        }
                        if (unary) {
                            string temp(1, s[i]);
                            ans.push_back(opname_map[temp]);
                        } else {
                            ans.push_back(s[i]);
                        }
                        break;
                    }
                    case 's':
                    case 'c':
                    case 't': {
                        if (i + 3 >= s.size()) {
                            err_no = -4;
                            cout << "bad op";
                            return "bad";
                        }
                        string temp = s.substr(i, 3);
                        if (opname_map.count(temp) == 0) {
                            err_no = -2;
                            cout << "op not exit";
                            return "bad";
                        }
                        ans.push_back(opname_map[temp]);
                        i += 2;
                        break;
                    }
                    default:
                        ans.push_back(s[i]);
                }
            }
            return ans;
        }
    
        void pop_until(char ch, stack<char> &st) {
            if (ch != '(' && priority(ch) < 0) {
                st.push(ch);
                return;
            }
            while (!st.empty() && st.top() != '(' && priority(st.top()) >= priority(ch)) {
                rpn.push_back(st.top());
                st.pop();
            }
            if (ch == ')') {
                st.pop();
            } else {
                st.push(ch);
            };
        }
    
    public:
        string getResult() {
            return result;
        }
    
        void pn_to_rpn(const string &s) {
            string fixStr = formatSpecialFix(s);
            if (err_no != 0) {
                return;
            }
            cout << fixStr << endl;
            stack<char> st;
            for (int i = 0; i < fixStr.size(); i++) {
                if (canMiss.count(fixStr[i])) {
                    continue;
                }
                if (isdigit(fixStr[i])) {
                    rpn.push_back(fixStr[i]);
                    while (i + 1 < fixStr.size() && (isdigit(fixStr[i + 1]) || fixStr[i + 1] == '.')) {
                        rpn.push_back(fixStr[i + 1]);
                        i++;
                    }
                } else if (fixStr[i] == '(') {
                    st.push(fixStr[i]);
                    continue;
                } else {
                    pop_until(fixStr[i], st);
                }
                rpn.push_back(' ');
            }
            while (!st.empty()) {
                rpn.push_back(st.top());
                st.pop();
            }
        }
    
        OPTYPE cal() {
            cout << rpn << endl;
            stack<OPTYPE> st;
            for (int i = 0; i < rpn.size(); i++) {
                // 空字符
                if (canMiss.count(rpn[i])) {
                    continue;
                }
                // 数字
                if (isdigit(rpn[i])) {
                    bool dot = false;
                    double base = 0.1;
                    OPTYPE value = rpn[i] - '0';
                    while (i + 1 < rpn.size() && (isdigit(rpn[i + 1]) || rpn[i + 1] == '.')) {
                        if (rpn[i + 1] == '.') {
                            dot = true;
                        } else {
                            if (!dot) {
                                value = value * 10 + (rpn[i + 1] - '0');
                            } else {
                                value += ((rpn[i + 1] - '0') * base);
                                base /= 10;
                            }
                        }
                        i++;
                    }
                    st.push(value);
                    continue;
                }
                if (opfunc_map.count(rpn[i]) == 0) {
                    err_no = -3;
                    cout << "unsupport op";
                    break;
                }
                auto op = opfunc_map[rpn[i]];
                auto v = op->cal(st);
                if (err_no != 0) {
                    break;
                }
                cout << v << endl;
                st.push(v);
            }
            if (err_no != 0) {
                return INT64_MIN;
            }
            cout << st.top() << endl;
            return st.top();
        }
    };
    
    unordered_map<string, char> RPN::opname_map{
            {"+",   'z'},
            {"-",   'y'},
            {"tan", 't'},
            {"sin", 's'},
            {"cos", 'c'},
    
    };
    
    unordered_set<char> RPN::canMiss{' '};
    
    unordered_map<char, Operator *> RPN::opfunc_map{
            {'z', new UnaryAddOperator},
            {'y', new UnarySubOperator},
            {'+', new AddOperator},
            {'-', new SubOperator},
            {'*', new MultiplyOpeator},
            {'/', new DivideOperator},
            {'s', new SinOperator},
            {'c', new CosOperator},
            {'t', new TanOperator},
            {'%', new ModOperator},
            {'&', new BitAndOperator},
    };
    
    extern "C" {
    OPTYPE calculate(const char *s) {
        err_no = 0;
        RPN rpn;
        rpn.pn_to_rpn(s);
        if (err_no != 0) {
            return INT64_MIN;
        }
        return rpn.cal();
    }
    }
    
    //
    int main() {
        cout << calculate("sincostan6");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402

    python UI 源码

    """
    实现带界面的计算器(可做加减乘除操作)
    
    """
    
    from tkinter import *
    import tkinter.font
    from functools import partial
    
    import ctypes
    import platform
    
    calculator = ctypes.CDLL('./cal.so')
    calculator.calculate.restype = ctypes.c_double
    
    
    def get_input(entry, argu):
        entry.insert(END, argu)
    
    
    def backspace(entry):
        input_len = len(entry.get())
        entry.delete(input_len - 1)
    
    
    def clear(entry):
        entry.delete(0, END)
    
    
    def calc(entry):
        input = entry.get().strip()
        #output2 = str(eval(input))
        # print(output2)
    
        bs = ctypes.c_char_p(bytes(input, encoding="utf8"))
        output = calculator.calculate(bs)
        if output == -9223372036854775808:
            output = 'error'
        clear(entry)
        # if output2 != output:
        #    entry.insert(END, output)
        #    entry.insert(END, "\t")
        #    entry.insert(END, output2)
        # else:
        entry.insert(END, output)
    
    
    
    def cal():
        root = Tk()
        root.title("我的计算器")
        root.resizable(0, 0)
    
        entry_font = tkinter.font.Font(size=12)
        entry = Entry(root, justify="right", font=entry_font)
        entry.grid(row=0, column=0, columnspan=4, sticky=N + W + S + E, padx=5, pady=5)
    
        button_font = tkinter.font.Font(size=10, weight=tkinter.font.BOLD)
        button_bg = '#D5E0EE'
        button_active_bg = '#E5E35B'
    
        myButton = partial(Button, root, bg=button_bg, padx=10, pady=3, activebackground=button_active_bg)
    
        button7 = myButton(text='7', command=lambda: get_input(entry, '7'))
        button7.grid(row=1, column=0, pady=5)
    
        button8 = myButton(text='8', command=lambda: get_input(entry, '8'))
        button8.grid(row=1, column=1, pady=5)
    
        button9 = myButton(text='9', command=lambda: get_input(entry, '9'))
        button9.grid(row=1, column=2, pady=5)
    
        button10 = myButton(text='+', command=lambda: get_input(entry, '+'))
        button10.grid(row=1, column=3, pady=5)
    
        button4 = myButton(text='4', command=lambda: get_input(entry, '4'))
        button4.grid(row=2, column=0, pady=5)
    
        button5 = myButton(text='5', command=lambda: get_input(entry, '5'))
        button5.grid(row=2, column=1, pady=5)
    
        button6 = myButton(text='6', command=lambda: get_input(entry, '6'))
        button6.grid(row=2, column=2, pady=5)
    
        button11 = myButton(text='-', command=lambda: get_input(entry, '-'))
        button11.grid(row=2, column=3, pady=5)
    
        button1 = myButton(text='1', command=lambda: get_input(entry, '1'))
        button1.grid(row=3, column=0, pady=5)
    
        button2 = myButton(text='2', command=lambda: get_input(entry, '2'))
        button2.grid(row=3, column=1, pady=5)
    
        button3 = myButton(text='3', command=lambda: get_input(entry, '3'))
        button3.grid(row=3, column=2, pady=5)
    
        button12 = myButton(text='*', command=lambda: get_input(entry, '*'))
        button12.grid(row=3, column=3, pady=5)
    
        button0 = myButton(text='0', command=lambda: get_input(entry, '0'))
        button0.grid(row=4, column=0, columnspan=1, padx=3, pady=5, sticky=N + S + E + W)
    
        button18 = myButton(text='%', command=lambda: get_input(entry, '%'))
        button18.grid(row=4, column=1, columnspan=1, padx=3, pady=5, sticky=N + S + E + W)
    
        button13 = myButton(text='.', command=lambda: get_input(entry, '.'))
        button13.grid(row=4, column=2, pady=5)
    
        button14 = Button(root, text='/', bg=button_bg, padx=10, pady=3,
                          command=lambda: get_input(entry, '/'))
        button14.grid(row=4, column=3, pady=5)
    
        button15 = Button(root, text='<-', bg=button_bg, padx=10, pady=3,
                          command=lambda: backspace(entry), activebackground=button_active_bg)
        button15.grid(row=5, column=0, pady=5)
    
        button16 = Button(root, text='C', bg=button_bg, padx=10, pady=3,
                          command=lambda: clear(entry), activebackground=button_active_bg)
        button16.grid(row=5, column=1, pady=5)
    
        button17 = Button(root, text='=', bg=button_bg, padx=10, pady=3,
                          command=lambda: calc(entry), activebackground=button_active_bg)
        button17.grid(row=5, column=2, columnspan=2, padx=3, pady=5, sticky=N + S + E + W)
    
        button19 = myButton(text='sin', command=lambda: get_input(entry, 'sin'))
        button19.grid(row=6, column=0, columnspan=1, padx=3, pady=5, sticky=N + S + E + W)
    
        button20 = myButton(text='cos', command=lambda: get_input(entry, 'cos'))
        button20.grid(row=6, column=1, columnspan=1, padx=3, pady=5, sticky=N + S + E + W)
    
        button21 = myButton(text='tan', command=lambda: get_input(entry, 'tan'))
        button21.grid(row=6, column=2, columnspan=2, padx=3, pady=5, sticky=N + S + E + W)
    
        button22 = myButton(text='(', command=lambda: get_input(entry, '('))
        button22.grid(row=7, column=0, columnspan=1, padx=3, pady=5, sticky=N + S + E + W)
    
        button23 = myButton(text=')', command=lambda: get_input(entry, ')'))
        button23.grid(row=7, column=1, columnspan=1, padx=3, pady=5, sticky=N + S + E + W)
    
        button24 = myButton(text='&', command=lambda: get_input(entry, '&'))
        button24.grid(row=7, column=2, columnspan=2, padx=3, pady=5, sticky=N + S + E + W)
    
        root.mainloop()
    
    
    if __name__ == '__main__':
        cal()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148

    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现
    c+±基本计算器的一般实现

  • 相关阅读:
    【数据结构初阶】八大排序(一)——希尔排序&&堆排序&&直接插入排序&&直接选择排序
    提示工程 vs 微调 vs RAG
    基于AT89C51的出租车计价器设计(全套毕设资料)
    独家下载|《阿里云MaxCompute百问百答》 解锁SaaS模式云数据仓库尽在本电子手册!
    荐书 | 为什么喜欢的女生这么难追?
    Ampere ARM Server 内核版本更新
    2023版 STM32实战4 滴答定时器精准延时
    C++构造函数和析构函数
    【数据库应用-1】——CDA
    【初阶与进阶C++详解】第十三篇:继承
  • 原文地址:https://blog.csdn.net/qq_34179431/article/details/126377175