2024-06-23 编译原理实验4——中间代码生成

文章目录

    • 一、实验要求
    • 二、实验设计
    • 三、实验结果
    • 四、附完整代码

补录与分享本科实验,以示纪念。

一、实验要求

在词法分析、语法分析和语义分析程序的基础上,将C−−源代码翻译为中间代码。
要求将中间代码输出成线性结构(三地址代码),使用虚拟机小程序(附录B)来测试中间代码的运行结果。
由于在后面的实验中还会用到本次实验已经写好的代码,因此保持一个良好的代码风格、系统地设计代码结构和各模块之间的接口对于整个实验来讲相当重要!

  • 基本要求
    1. 对于正确的测试样例,输出可以在虚拟机上运行的中间代码文件。
    2. 在程序可以生成正确的中间代码(“正确”是指该中间代码在虚拟机小程序上运行结果正确)的前提下,效率也是最终评分的关键因素。
  • 附加要求
  1. 修改前面对C−−源代码的假设2和3,使源代码中:
    a) 可以出现结构体类型的变量(但不会有结构体变量之间直接赋值)。
    b) 结构体类型的变量可以作为函数的参数(但函数不会返回结构体类型的值)。
  2. 修改前面对C−−源代码的假设2和3,使源代码中:
    c) 一维数组类型的变量可以作为函数参数(但函数不会返回一维数组类型的值)。
    d) 可以出现高维数组类型的变量(但高维数组类型的变量不会作为函数的参数或返回类值)。

本实验只实现了abc,没有实现d。

二、实验设计

1、translate
该函数使用switch-case寻找需要处理的节点进行处理,否则继续寻找下层结点:

void translate(Node *h) {
    if (h == NULL) return;
    switch (h->type) {
        case Specifier:
            return;
        case FunDec: {
            translateFunDec(h);
            break;
        }
        case Dec: {
            translateDec(h);
            break;
        }
        case Stmt: {
            translateStmt(h);
            break;
        }
        default: {
            for (int i = 0; i < h->childNum; i++)
                translate(h->child[i]);
            break;
        }
    }
}

语义分析需要对每个匹配的产生式进行分析,因此需要写专门的函数进行操作。每个函数的操作均不一样,但也拥有相同的操作:

bool checkNode(Node *node, Types type) {
   if (node == NULL) {
      addLogNullNode(type);
      return false;
   }
   else if (node->type != type) {
      addLogTypeDismatch(type);
      return false;
   }
   addLogStartDealing(type);
   return true;
}

bool hasBrothers(Node *node, int n, ...) {
   va_list vaList;
   va_start(vaList, n);
   Types next;
   for (int i = 0; i < n; ++i) {
      next = va_arg(vaList, Types);
      if (node == NULL || next != node->type) return false;
      node = node->brother;
   }
   return node == NULL;
}

2、translateExp
我们注意到,一个exp的处理需要分两种情况:刚定义和已定义。即未被处理和已被处理过。于是我们添加了一个参数option:option = 0表示exp未被用过,option = 1表示exp已被用过。
这样做的另一个好处是,可以实现exp值的向上传递。
因此,translateExp函数对每一个匹配的产生式都进行了两种处理:option = 0和option = 1。

void translateExp(Node *h, char *place, int option) {
    if (h->child[0]->type == _LP) {
        return translateExp(h->child[1], place, option);
    } else if (h->childNum == 3 && h->child[1]->type == _ASSIGNOP) {
        char temp[MAX_LENGTH];
        translateExp(h->child[0], temp, 0);
        translateExp(h->child[2], temp, 1);
        if (place != NULL) {
            if (option == 0) {
                strcpy(place, temp);
            } else {
                addIrCode(3, place, ":=", temp);
            }
        }
    } else if (h->childNum == 3 && h->child[1]->type == _LP) {
        if (place == NULL) {
            if (strcmp(h->child[0]->name, "read") == 0)
                return;
            char temp[MAX_LENGTH];
            newTemp(temp);
            addIrCode(4, temp, ":=", "CALL", h->child[0]->name);
        } else {
            if (option == 0)
                newTemp(place);
            if (strcmp(h->child[0]->name, "read") == 0)
                addIrCode(2, "READ", place);
            else
                addIrCode(4, place, ":=", "CALL", h->child[0]->name);
        }
    } else if (h->childNum == 4 && h->child[1]->type == _LP) {
        if (place == NULL) {
            if (strcmp(h->child[0]->name, "write") == 0) {
                char temp[MAX_LENGTH];
                translateExp(h->child[2]->child[0], temp, 0);
                addIrCode(2, "WRITE", temp);
            } else {
                FunDefUnit *f = getFunction(h->child[0]->name);
                translateArgs(h->child[2], f->parameterList, 0);
                char temp[MAX_LENGTH];
                newTemp(temp);
                addIrCode(4, temp, ":=", "CALL", h->child[0]->name);
            }
        } else {
            if (strcmp(h->child[0]->name, "write") == 0) {
                char temp[MAX_LENGTH];
                translateExp(h->child[2]->child[0], temp, 0);
                addIrCode(2, "WRITE", temp);
                if (option == 0) {
                    place[0] = '#';
                    place[1] = '0';
                    place[2] = '\0';
                } else {
                    addIrCode(3, place, ":=", "#0");
                }
            } else {
                FunDefUnit *f = getFunction(h->child[0]->name);
                translateArgs(h->child[2], f->parameterList, 0);
                if (option == 0)
                    newTemp(place);
                addIrCode(4, place, ":=", "CALL", h->child[0]->name);
            }
        }
    }
    if (place == NULL)return;
    if (h->child[0]->type == _INT) {
        if (option == 0) {
            sprintf(place, "#%d", h->child[0]->intValue);
        } else {
            char temp[MAX_LENGTH];
            sprintf(temp, "#%d", h->child[0]->intValue);
            addIrCode(3, place, ":=", temp);
        }
    } else if (h->child[0]->type == _ID && h->childNum == 1) {
        if (option == 0) {
            strcpy(place, h->child[0]->name);
        } else {
            addIrCode(3, place, ":=", h->child[0]->name);
        }
    } else if (h->childNum == 3 &&
               (h->child[1]->type == _PLUS || h->child[1]->type == _MINUS || h->child[1]->type == _STAR ||
                h->child[1]->type == _DIV)) {
        char temp1[MAX_LENGTH], temp2[MAX_LENGTH];
        translateExp(h->child[0], temp1, 0);
        if ((temp1[0] == '#' && temp1[1] == '0') && (h->child[1]->type == _STAR || h->child[1]->type == _DIV)) {
            if (option == 0) {
                place[0] = '#';
                place[1] = '0';
                place[2] = '\0';
            } else {
                addIrCode(3, place, ":=", "#0");
            }
        }
        translateExp(h->child[2], temp2, 0);
        if ((temp2[0] == '#' && temp2[1] == '0') && (h->child[1]->type == _STAR || h->child[1]->type == _DIV)) {
            if (option == 0) {
                place[0] = '#';
                place[1] = '0';
                place[2] = '\0';
            } else {
                addIrCode(3, place, ":=", "#0");
            }
        } else if (temp1[0] == '#' && temp2[0] == '#') {
            int i1 = strtol(&temp1[1], NULL, 10);
            int i2 = strtol(&temp2[1], NULL, 10);
            if (h->child[1]->type == _PLUS) {
                if (option == 0) {
                    sprintf(place, "#%d", i1 + i2);
                } else {
                    char temp[MAX_LENGTH];
                    sprintf(temp, "#%d", i1 + i2);
                    addIrCode(3, place, ":=", temp);
                }
            } else if (h->child[1]->type == _MINUS) {
                if (option == 0) {
                    sprintf(place, "#%d", i1 - i2);
                } else {
                    char temp[MAX_LENGTH];
                    sprintf(temp, "#%d", i1 - i2);
                    addIrCode(3, place, ":=", temp);
                }
            } else if (h->child[1]->type == _STAR) {
                if (option == 0) {
                    sprintf(place, "#%d", i1 * i2);
                } else {
                    char temp[MAX_LENGTH];
                    sprintf(temp, "#%d", i1 * i2);
                    addIrCode(3, place, ":=", temp);
                }
            } else {
                if (option == 0) {
                    sprintf(place, "#%d", i1 / i2);
                } else {
                    char temp[MAX_LENGTH];
                    sprintf(temp, "#%d", i1 / i2);
                    addIrCode(3, place, ":=", temp);
                }
            }
        } else if (temp2[0] == '#' && temp2[1] == '0') {
            if (option == 0)
                strcpy(place, temp1);
            else
                addIrCode(3, place, ":=", temp1);
        } else if (temp1[0] == '#' && temp1[1] == '0' && h->child[1]->type == _PLUS) {
            if (option == 0)
                strcpy(place, temp2);
            else
                addIrCode(3, place, ":=", temp2);
        } else {
            char op[2];
            op[1] = '\0';
            if (h->child[1]->type == _PLUS) op[0] = '+';
            else if (h->child[1]->type == _MINUS) op[0] = '-';
            else if (h->child[1]->type == _STAR) op[0] = '*';
            else op[0] = '/';
            if (option == 0) {
                newTemp(place);
            }
            addIrCode(5, place, ":=", temp1, op, temp2);
        }
    } else if (h->child[0]->type == _MINUS) {
        char temp[MAX_LENGTH];
        translateExp(h->child[1], temp, 0);
        if (temp[0] == '#') {
            int i = strtol(&temp[1], NULL, 10);
            if (option == 0) {
                sprintf(place, "#%d", -i);
            } else {
                char temp1[MAX_LENGTH];
                sprintf(temp1, "#%d", -i);
                addIrCode(3, place, ":=", temp1);
            }
        } else {
            if (option == 0) {
                newTemp(place);
            }
            addIrCode(5, place, ":=", "#0", "-", temp);
        }
    } else if (h->child[0]->type == _NOT || h->child[1]->type == _RELOP || h->child[1]->type == _AND ||
               h->child[1]->type == _OR) {
        char label1[MAX_LENGTH], label2[MAX_LENGTH];
        newLabel(label1);
        newLabel(label2);
        if (option == 0)
            newTemp(place);
        addIrCode(3, place, ":=", "#0");
        translateCond(h, label1, label2);
        addIrCode(3, "LABEL", label1, ":");
        addIrCode(3, place, ":=", "#1");
        addIrCode(3, "LABEL", label2, ":");
    } else if (h->childNum == 4 && h->child[1]->type == _LB) {
        char temp1[MAX_LENGTH], temp2[MAX_LENGTH];
        getLocation(h->child[0], temp1);
        translateExp(h->child[2], temp2, 0);
        if (temp2[0] == '#' && temp2[1] == '0') {
            char temp[MAX_LENGTH];
            if (temp1[0] == '&')
                strcpy(temp, &temp1[1]);
            else
                sprintf(temp, "*%s", temp1);
            if (option == 0) {
                strcpy(place, temp);
            } else {
                addIrCode(3, place, ":=", temp);
            }
        } else if (temp2[0] == '#') {
            int i = strtol(&temp2[1], NULL, 10);
            char temp[MAX_LENGTH], tempi[MAX_LENGTH];
            sprintf(tempi, "#%d", i * currentSize);
            newTemp(temp);
            addIrCode(5, temp, ":=", temp1, "+", tempi);
            char result[MAX_LENGTH];
            sprintf(result, "*%s", temp);
            if (option == 0)
                strcpy(place, result);
            else
                addIrCode(3, place, ":=", result);
        } else {
            char temp[MAX_LENGTH], tempi[MAX_LENGTH], result[MAX_LENGTH], num[MAX_LENGTH];
            sprintf(num, "#%d", currentSize);
            newTemp(temp);
            newTemp(tempi);
            addIrCode(5, tempi, ":=", temp2, "*", num);
            addIrCode(5, temp, ":=", temp1, "+", tempi);
            sprintf(result, "*%s", temp);
            if (option == 0)
                strcpy(place, result);
            else
                addIrCode(3, place, ":=", result);
        }
    } else if (h->childNum == 3 && h->child[1]->type == _DOT) {
        char left[MAX_LENGTH], temp[MAX_LENGTH], result[MAX_LENGTH];
        getLocation(h->child[0], left);
        int offseti = structGetOffset(currentStruct, h->child[2]->name);
        char offset[MAX_LENGTH];
        sprintf(offset, "#%d", offseti);
        newTemp(temp);
        addIrCode(5, temp, ":=", left, "+", offset);
        sprintf(result, "*%s", temp);
        if (option == 0)
            strcpy(place, result);
        else
            addIrCode(3, place, ":=", result);
    }
}

3、translateStmt
和translate函数类似,匹配每一个产生式做出相应的操作,其中可以用到translateExp处理exp结点:

void translateStmt(Node *h) {
    switch (h->child[0]->type) {
        case Exp: {
            translateExp(h->child[0], NULL, 0);
            break;
        }
        case CompSt: {
            translate(h->child[0]);
            break;
        }
        case _RETURN: {
            char temp[MAX_LENGTH];
            translateExp(h->child[1], temp, 0);
            addIrCode(2, "RETURN", temp);
            break;
        }
        case _IF: {
            char label1[MAX_LENGTH], label2[MAX_LENGTH], label3[MAX_LENGTH];
            newLabel(label1);
            newLabel(label2);
            if (h->childNum == 7) {
                newLabel(label3);
            }
            translateCond(h->child[2], label1, label2);
            addIrCode(3, "LABEL", label1, ":");
            translate(h->child[4]);
            if (h->childNum == 7)
                addIrCode(2, "GOTO", label3);
            addIrCode(3, "LABEL", label2, ":");
            if (h->childNum == 7) {
                translate(h->child[6]);
                addIrCode(3, "LABEL", label3, ":");
            }
            break;
        }
        case _WHILE: {
            char label1[MAX_LENGTH], label2[MAX_LENGTH], label3[MAX_LENGTH];
            newLabel(label1);
            newLabel(label2);
            newLabel(label3);
            addIrCode(3, "LABEL", label1, ":");
            translateCond(h->child[2], label2, label3);
            addIrCode(3, "LABEL", label2, ":");
            translate(h->child[4]);
            addIrCode(2, "GOTO", label1);
            addIrCode(3, "LABEL", label3, ":");
            break;
        }
    }
}

4、translateArgs
(1)如果Args→Exp COMMA Args,则继续处理Args,即函数的第一个if语句。
(2)分情况考虑,如果exp不为数组或结构,则翻译exp,即函数的第二个if语句。
(3)否则,exp为数组或结构。首先使用getlocation函数获取其地址,然后将其加入irCode。

void translateArgs(Node *h, VarDefUnit **args, int count) {
    if (h->childNum == 3)
        translateArgs(h->child[2], args, count + 1);
    if (args[count]->varType != _ARR_STRUCT_) {
        char temp[MAX_LENGTH];
        translateExp(h->child[0], temp, 0);
        addIrCode(2, "ARG", temp);
    }else {
        char temp[MAX_LENGTH];
        getLocation(h->child[0], temp);
        addIrCode(2, "ARG", temp);
    }
}

三、实验结果

  1. t1.cmm
int main()
{
    int n;
    n = read();
    if (n > 0) write(1); 
    else if (n < 0) write (-1);
    else write(0);
    return 0;
}

执行中间代码生成:

中间代码:

FUNCTION main :
READ n
IF n > #0 GOTO label0
GOTO label1
LABEL label0 :
WRITE #1
GOTO label2
LABEL label1 :
IF n < #0 GOTO label3
GOTO label4
LABEL label3 :
WRITE #-1
GOTO label5
LABEL label4 :
WRITE #0
LABEL label5 :
LABEL label2 :
RETURN #0

中间代码执行结果(输入 2):

  1. t2.cmm
int fact(int n)
{
    if (n == 1)
        return n;
    else
        return (n * fact(n - 1));
}

int main()
{
    int m, result;
    m = read();
    if (m > 1)
        result = fact(m);
    else
        result = 1;
    write(result);
    return 0;
}

执行中间代码生成:

中间代码:

FUNCTION fact :
PARAM n
IF n == #1 GOTO label0
GOTO label1
LABEL label0 :
RETURN n
GOTO label2
LABEL label1 :
_t0 := n - #1
ARG _t0
_t1 := CALL fact
_t2 := n * _t1
RETURN _t2
LABEL label2 :
FUNCTION main :
READ m
IF m > #1 GOTO label3
GOTO label4
LABEL label3 :
ARG m
result := CALL fact
GOTO label5
LABEL label4 :
result := #1
LABEL label5 :
WRITE result
RETURN #0

中间代码执行结果(输入 5):

  1. t3.cmm
struct Operands
{
    int o1;
    int o2;
};

int add(struct Operands temp)
{
	return (temp.o1 + temp.o2);
}

int main()
{
    int n;
    struct Operands op;
    op.o1 = 1;
    op.o2 = 2;
    n = add(op);
    write(n);
    return 0;
}

执行中间代码生成:

中间代码:

FUNCTION add :
PARAM temp
_t0 := temp + #0
_t1 := temp + #4
_t2 := *_t0 + *_t1
RETURN _t2
FUNCTION main :
DEC op 8
_t3 := &op + #0
*_t3 := #1
_t4 := &op + #4
*_t4 := #2
ARG &op
n := CALL add
WRITE n
RETURN #0

中间代码执行结果:

  1. t4.cmm
int add(int temp[2])
{
   return (temp[0] + temp[1]);
}

int main()
{
    int op[2];
    int r[1][2];
    int i = 0, j = 0;
    while (i < 2) {
  	    while (j < 2) {
            op[j] = i + j;
            j = j + 1;
        }
        r[0][i] = add(op);
        write(r[0][i]);
        i = i + 1;
        j = 0;
    }
    return 0;
}

执行中间代码生成:

中间代码:

FUNCTION add :
PARAM temp
_t0 := temp + #4
_t1 := *temp + *_t0
RETURN _t1
FUNCTION main :
DEC op 8
DEC r 8
i := #0
j := #0
LABEL label0 :
IF i < #2 GOTO label1
GOTO label2
LABEL label1 :
LABEL label3 :
IF j < #2 GOTO label4
GOTO label5
LABEL label4 :
_t3 := j * #4
_t2 := &op + _t3
_t8 := i + j
*_t2 := _t8
j := j + #1
GOTO label3
LABEL label5 :
_t5 := i * #8
_t4 := &r + _t5
ARG &op
_t9 := CALL add
*_t4 := _t9
_t7 := i * #8
_t6 := &r + _t7
WRITE *_t6
i := i + #1
j := #0
GOTO label0
LABEL label2 :
RETURN #0

中间代码执行结果:

四、附完整代码

github 链接:https://github.com/zheliku/byyl---Intermediate-Code-Generation。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CTFHUB-SSRF-POST请求

通过file协议访问flag.php文件内容 ?urlfile:///var/www/html/flag.php 右键查看页面源代码 需要从内部携带key发送post数据包即可获得flag ?urlhttp://127.0.0.1/flag.php 得到了key 构造POST请求数据包&#xff0c;进行url编码&#xff08;新建一个txt文件&#xff0c;…

【vue3|第12期】Vue3的Props详解:组件通信

日期&#xff1a;2024年6月19日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

微服务——重复消费(幂等解决方案)

目录 一、唯一ID机制二、幂等性设计三、状态检查机制四、利用缓存和消息队列五、分布式锁总结 在微服务中&#xff0c;防止重复消费的核心思想是通过设计使得操作一次与多次产生相同的效果&#xff0c;并为每次操作生成唯一的ID。这样&#xff0c;即使在消息被重复发送的情况下…

Stable Diffusion 插件安装与推荐,助力你的AI绘图

在上一篇文章我们安装了Stable Diffusion &#xff0c;这篇文章我们来安装Stable Diffusion的插件 Stable Diffusion的插件是绘画中重要的一环&#xff0c;好的插件可以让你的绘画更加得心应手 中英双语插件 为什么要安装中英双语插件呢&#xff0c;不能只安装中文插件吗&…

计算机组成原理 | 数据的表示、运算和校验(1)数值型数据

有了一个二进制代码&#xff0c;首先要知道他是带符号的还是不带符号的&#xff0c;接着要知道他是原码还是补码还是反码&#xff0c;最终才能确定他的真值。 补码和移码&#xff1a;符号相反、数值位相同 表示范围不理解 数的定点表示法 对于反码而言&#xff1a;10000000表示…

Android蓝牙开发(一)之打开蓝牙和设备搜索

private BluetoothManager bluetoothmanger; private​ BluetoothAdapter bluetoothadapter; /** 判断设备是否支持蓝牙 */ bluetoothmanger (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); bluetoothadapter bluetoothmanger.getAdapter(); if (bl…

46、基于自组织映射神经网络的鸢尾花聚类(matlab)

1、自组织映射神经网络的鸢尾花聚类的原理及流程 自组织映射神经网络&#xff08;Self-Organizing Map, SOM&#xff09;是一种用于聚类和数据可视化的人工神经网络模型。在鸢尾花聚类中&#xff0c;SOM 可以用来将鸢尾花数据集分成不同的类别&#xff0c;同时保留数据间的拓扑…

MyBatisPlus中的selectById方法

今天在编代码时用selectById方法时&#xff0c;不小心写错了&#xff0c;参数传了个实体类。本来应该传id的。 但是没报错&#xff0c;于是进入源码看了一下。 这是源码 里面的参数是一个序列化类型的。 后面发现我的实体类实现了这个接口所以能才能传进去。不实现就传不了 我…

SSL/TLS握手

文章目录 SSL/TLSTLS历史发展层次结构SSL/TLS握手协议TLS1.2 Vs TLS1.3 安全通信协议是一类用于保护计算机网络上数据传输安全的协议。这些协议通过加密、身份验证和数据完整性机制来防止数据被窃听、篡改或伪造。以下是一些主要的安全通信协议&#xff1a;SSL/TLS, IPsec, SSH…

idea配置本地maven

软件名地址链接说明MavenMaven – Download Apache Maven依赖管理 下载bin.zip 环境变量 测试安装 修改配置文件 本地依赖存储位置 新建文件夹 修改配置 国内镜像源 <mirror><id>alimaven</id><mirrorOf>central</mirrorOf><name>ali…

大电流一体成型电感CSEB1350系列,助力实现DC-DC转换器小尺寸、高效率

DC-DC转换器 , 转换器 , 科达嘉 DC-DC转换器作为一种电压转换装置&#xff0c;在电子产品、电源系统、工业控制、新能源等领域广泛应用。。。 DC-DC转换器作为一种电压转换装置&#xff0c;在电子产品、电源系统、工业控制、新能源等领域广泛应用。随着各行业用户对DC-DC转换器…

pytorch神经网络训练(VGG-16)

VGG-16 导包 import torchimport torch.nn as nnimport torch.optim as optimimport torchvisionfrom torchvision import datasets, transformsfrom torch.utils.data import DataLoaderimport matplotlib.pyplot as plt 数据预处理和增强 transform transforms.Compose(…

Flutter-实现头像叠加动画效果

实现头像叠加动画效果 在这篇文章中&#xff0c;我们将介绍如何使用 Flutter 实现一个带有透明度渐变效果和过渡动画的头像叠加列表。通过这种效果&#xff0c;可以在图片切换时实现平滑的动画&#xff0c;使 UI 更加生动和吸引人。 需求 我们的目标是实现一个头像叠加列表&…

基于顺序存储的环形队列算法库构建

学习贺利坚老师基于数组的环形队列 数据结构之自建算法库——顺序环形队列_下空队列q中依次入队列数据元素abc-CSDN博客文章浏览阅读5.2k次&#xff0c;点赞6次&#xff0c;收藏6次。本文针对数据结构基础系列网络课程(3)&#xff1a;栈和队列中第9课时环形队列的存储及基本操…

基于ESP8266串口WIFI模块ESP-01S在Station模式(即接收无线信号( WiFi))下实现STC单片机与手机端网路串口助手相互通信功能

基于ESP8266串口WIFI模块ESP-01S在Station模式(即接收无线信号( WiFi))下实现STC单片机与手机端网路串口助手相互通信功能 ESP8266_01S引脚功能图ESP8266_01S原理图ESP8266_01S尺寸图检验工作1、USB-TTL串口工具(推荐使用搭载CP2102芯片的安信可USB-T1串口)与ESP8266_01S…

会声会影2024永久破解和谐版下载 包含激活码序列号

亲爱的创作伙伴们&#xff0c;今天我要分享一个让我的影视编辑生活大放异彩的神器——会声会影2024破解版本&#xff01;&#x1f389;&#x1f31f; &#x1f308;**功能全面升级**&#xff1a;作为一款专业的视频编辑软件&#xff0c;会声会影2024破解版本不仅继承了之前版本…

KEITHLEY吉时利24611kW 脈沖模式 SourceMeter 手侧

KEITHLEY吉时利24611kW 脈沖模式 SourceMeter 手侧

【vue3|第13期】深入了解Vue3生命周期:管理组件的诞生、成长与消亡

日期&#xff1a;2024年6月22日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xf…

【大数据 复习】第8章 Hadoop架构再探讨

一、概念 1.Hadoop1.0的核心组件&#xff08;仅指MapReduce和HDFS&#xff0c;不包括Hadoop生态系统内的Pig、Hive、HBase等其他组件&#xff09;&#xff0c;主要存在以下不足&#xff1a; &#xff08;1&#xff09;抽象层次低&#xff0c;需人工编码 &#xff08;2&#xf…

【Linux】基础IO_4

文章目录 六、基础I/O4. 动静态库 未完待续 六、基础I/O 4. 动静态库 既然我们能够成功创建静态库了&#xff0c;接下来我们将这个代码打包成动态库&#xff1a; shared: 表示生成共享库格式 fPIC&#xff1a;产生位置无关码(position independent code) 动态库库名规则&…