(linux基础IO)编写简单的add/sub/mul/div函数,并打包成动/静态库,并分别使用

编写简单的add/sub/mul/div函数,并打包成动/静态库,并分别使用

  • 静态库(.a):在windows下后缀为(.lid),程序在编译链接的时候把库的代码链接到可执行文件里。程序运行的时候将不再需要静态库。
  • 动态库(.so):在windows下后缀为(.dll),程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。
  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程叫动态链接。
  • 动态库可以在多个程序间共享,所以动态链接使用可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一部分动态库被要到该库的所有进程共用,节省了内存和磁盘空间。

静态库

编写简单的add/sub/mul/div函数,并打包成静态库,并使用

第一步:分别创建.h.c文件

首先创建 add.h /sub.h /mul.h /div.h
在这里插入图片描述
内容如下:
在这里插入图片描述
然后创建 add.c/sub.c /mul.c /div.c
在这里插入图片描述
内容如下:
在这里插入图片描述

第二步:创建好.h 和 .c 文件之后gcc -c add.c sub.c mul.c div.c 编译生成.o文件
在这里插入图片描述

第三步:将编译生成的文件用以下命令生成静态库: ar -cr libsmath.a ./*.o
在这里插入图片描述

注意:这里的库名是叫smath,要生成静态库,需要给前面加上lib,后面加上.a。
ar是gnu归档工具,cr表示 create and replace
./*.o 表示的是当前目录下的所有的.o后缀文件

第四步:创建一个测试目录,将上一级的静态库和.h都拷贝过来
在这里插入图片描述

第五步:创建一个test.c文件来实现函数功能
.
创建的test.c文件内容如下:
在这里插入图片描述

第六步:生成可执行程序test: gcc test.c -o test -L. -lsmath在这里插入图片描述
命令的意思是在当前目录下查找库。-L. 指定库路径 -l 指定库名。
注意,在-l时要同时去掉前缀和后缀。
测试目标文件生成后,静态库删掉,程序照样运行。

动态库

编写简单的add/sub/mul/div函数,并打包成动态库,并使用

第一步:首先将上面创建好的代码拷贝到新目录下
在这里插入图片描述

第二步:通过gcc -c编译生成.o文件:命令[ gcc -fPIC -c ./*.c ] 不过这里要加上-fPIC:产生位置无关码,使它加载到哪里都能运行
在这里插入图片描述

第三步:生成动态库:gcc -shared ./*.o -o libdlib.so
shared:表示生成共享库格式,库(dlib)的前面加上lib后缀要加上.so
*.o 表示所有.o文件
在这里插入图片描述

第四步:创建一个测试文件,把头文件(.h)和动态库(.so)拷贝进去
在这里插入图片描述

第五步:把之前的test.c拷到当前目录
在这里插入图片描述

第六步:生成可执行程序: gcc test.c -o test -L. -ldlib
在这里插入图片描述中间不小心敲错,直接马掉

第七步:运行可执行程序
这里需要引入一个环境变量LD_LIBRARY_PATH,它是系统查找动态库的路径
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PL/0编译程序主要包含了词法分析、语法分析和语义分析三个部分。语法分析阶段通常会生语法树作为中间结果,而语义分析阶段则会对语法树进行遍历,进行类型检查、作用域检查和代码生等操作。 下面是一个示例代码,演示如何使用C++语言编写PL/0编译程序的语义分析程序,并生四元式形式的中间代码: ```cpp #include <iostream> #include <string> #include <vector> #include <algorithm> #include <map> using namespace std; // Token类,表示词法分析的结果 class Token { public: enum class Type { Identifier, Number, Operator, Keyword, Delimiter, EndOfFile }; Token(Type type, string value): type_(type), value_(value) {} Type type() const { return type_; } string value() const { return value_; } private: Type type_; string value_; }; // 符号表项类,表示一个变量或常量的信息 class Symbol { public: enum class Type { Variable, Constant }; Symbol(Type type, string name, int level, int address, int value = 0) : type_(type), name_(name), level_(level), address_(address), value_(value) {} Type type() const { return type_; } string name() const { return name_; } int level() const { return level_; } int address() const { return address_; } int value() const { return value_; } private: Type type_; string name_; int level_; int address_; int value_; }; // 四元式类,表示中间代码的一条指令 class Quadruple { public: enum class Operator { Add, Sub, Mul, Div, Assign, Load, Store, Push, Pop, Jmp, JmpIf, JmpIfNot, Call, Ret }; Quadruple(Operator op, string arg1, string arg2, string result) : op_(op), arg1_(arg1), arg2_(arg2), result_(result) {} Operator op() const { return op_; } string arg1() const { return arg1_; } string arg2() const { return arg2_; } string result() const { return result_; } private: Operator op_; string arg1_; string arg2_; string result_; }; // PL/0编译程序类,包含词法分析、语法分析和语义分析等功能 class Compiler { public: Compiler(string source): source_(source) {} void compile() { // 词法分析 tokenize(); // 语法分析 parse(); // 语义分析 analyze(); // 代码生 generate(); } private: // 词法分析部分 void tokenize() { // TODO: 实现词法分析部分 } // 语法分析部分 void parse() { // TODO: 实现语法分析部分 } // 语义分析部分 void analyze() { // 初始化符号表 symbols_.push_back(Symbol(Symbol::Type::Variable, "", 0, 0)); // 空符号表 // 遍历语法树,进行类型检查、作用域检查和代码生 analyzeNode(root_); } // 对语法树节点进行语义分析 void analyzeNode(Node* node) { if (node->type == Node::Type::Program) { // 程序节点,遍历子节点 for (auto child : node->children) { analyzeNode(child); } } else if (node->type == Node::Type::Block) { // 块节点,进入新的作用域并遍历子节点 enterScope(); for (auto child : node->children) { analyzeNode(child); } exitScope(); } else if (node->type == Node::Type::VarDecl) { // 变量声明节点,将变量添加到符号表中 for (auto child : node->children) { if (child->type == Node::Type::Identifier) { string name = child->token.value(); int address = allocate(); symbols_.push_back(Symbol(Symbol::Type::Variable, name, currentLevel(), address)); } } } else if (node->type == Node::Type::ConstDecl) { // 常量声明节点,将常量添加到符号表中 for (auto child : node->children) { if (child->type == Node::Type::Identifier) { string name = child->token.value(); int value = stoi(child->sibling->token.value()); symbols_.push_back(Symbol(Symbol::Type::Constant, name, currentLevel(), 0, value)); } } } else if (node->type == Node::Type::AssignStmt) { // 赋值语句节点,生赋值指令 string varName = node->token.value(); Symbol* symbol = findSymbol(varName); if (symbol == nullptr) { error("Undefined variable: " + varName); } analyzeNode(node->children[0]); quadruples_.push_back(Quadruple(Quadruple::Operator::Assign, pop(), "", symbol->name())); } else if (node->type == Node::Type::ReadStmt) { // 读取语句节点,生读取指令 string varName = node->token.value(); Symbol* symbol = findSymbol(varName); if (symbol == nullptr) { error("Undefined variable: " + varName); } quadruples_.push_back(Quadruple(Quadruple::Operator::Load, "", "", "stdin")); quadruples_.push_back(Quadruple(Quadruple::Operator::Store, pop(), "", symbol->name())); } else if (node->type == Node::Type::WriteStmt) { // 输出语句节点,生输出指令 analyzeNode(node->children[0]); quadruples_.push_back(Quadruple(Quadruple::Operator::Load, "", "", "stdout")); quadruples_.push_back(Quadruple(Quadruple::Operator::Push, pop(), "", "")); quadruples_.push_back(Quadruple(Quadruple::Operator::Call, "", "", "print")); } else if (node->type == Node::Type::IfStmt) { // 条件语句节点,生条件跳转指令 analyzeNode(node->children[0]); quadruples_.push_back(Quadruple(Quadruple::Operator::JmpIfNot, pop(), "", "")); analyzeNode(node->children[1]); } else if (node->type == Node::Type::IfElseStmt) { // 条件语句(含有else分支)节点,生条件跳转指令和无条件跳转指令 analyzeNode(node->children[0]); quadruples_.push_back(Quadruple(Quadruple::Operator::JmpIfNot, pop(), "", "")); analyzeNode(node->children[1]); int label1 = allocateLabel(); quadruples_.push_back(Quadruple(Quadruple::Operator::Jmp, "", "", toLabel(label1))); setLabel(label1); analyzeNode(node->children[2]); } else if (node->type == Node::Type::WhileStmt) { // 循环语句节点,生条件跳转指令和无条件跳转指令 int label1 = allocateLabel(); setLabel(label1); analyzeNode(node->children[0]); quadruples_.push_back(Quadruple(Quadruple::Operator::JmpIfNot, pop(), "", "")); analyzeNode(node->children[1]); quadruples_.push_back(Quadruple(Quadruple::Operator::Jmp, "", "", toLabel(label1))); } else if (node->type == Node::Type::CallStmt) { // 调用语句节点,生调用指令 string funcName = node->token.value(); quadruples_.push_back(Quadruple(Quadruple::Operator::Call, "", "", funcName)); } else if (node->type == Node::Type::ReturnStmt) { // 返回语句节点,生返回指令 analyzeNode(node->children[0]); quadruples_.push_back(Quadruple(Quadruple::Operator::Ret, "", "", "")); } else if (node->type == Node::Type::Expression) { // 表达式节点,生表达式指令 analyzeExpression(node); } else if (node->type == Node::Type::Identifier) { // 标识符节点,生加载指令 string varName = node->token.value(); Symbol* symbol = findSymbol(varName); if (symbol == nullptr) { error("Undefined variable: " + varName); } quadruples_.push_back(Quadruple(Quadruple::Operator::Load, "", "", symbol->name())); push(symbol->name()); } else if (node->type == Node::Type::Number) { // 数字节点,生常量指令 int value = stoi(node->token.value()); string name = toConstant(value); quadruples_.push_back(Quadruple(Quadruple::Operator::Load, "", "", name)); push(name); } else if (node->type == Node::Type::Operator) { // 运算符节点,生运算指令 analyzeExpression(node); } } // 对表达式节点进行语义分析 void analyzeExpression(Node* node) { if (node->type == Node::Type::Expression) { analyzeExpression(node->children[0]); if (node->children.size() == 3) { analyzeExpression(node->children[2]); string arg2 = pop(); string arg1 = pop(); string result = newTemp(); switch (node->children[1]->token.type()) { case Token::Type::Operator: switch (node->children[1]->token.value()[0]) { case '+': quadruples_.push_back(Quadruple(Quadruple::Operator::Add, arg1, arg2, result)); break; case '-': quadruples_.push_back(Quadruple(Quadruple::Operator::Sub, arg1, arg2, result)); break; case '*': quadruples_.push_back(Quadruple(Quadruple::Operator::Mul, arg1, arg2, result)); break; case '/': quadruples_.push_back(Quadruple(Quadruple::Operator::Div, arg1, arg2, result)); break; } break; case Token::Type::Keyword: if (node->children[1]->token.value() == "and") { quadruples_.push_back(Quadruple(Quadruple::Operator::Mul, arg1, arg2, result)); } else if (node->children[1]->token.value() == "or") { quadruples_.push_back(Quadruple(Quadruple::Operator::Add, arg1, arg2, result)); quadruples_.push_back(Quadruple(Quadruple::Operator::Push, result, "", "")); quadruples_.push_back(Quadruple(Quadruple::Operator::Load, "", "", toConstant(0))); quadruples_.push_back(Quadruple(Quadruple::Operator::JmpIfNot, pop(), "", "")); quadruples_.push_back(Quadruple(Quadruple::Operator::Push, toConstant(1), "", ""));
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值