【Compile】递归下降语法分析(C++)

从零实现编译器:词法分析、语法分析与代码生成实战 编译器作为连接高级编程语言与机器指令的核心系统软件,其工作原理是每个开发者深入理解计算机科学的关键。编译过程通常遵循词法分析、语法分析、语义分析、代码生成等核心阶段,其中词法分析负责将源代码字符串拆分为有意义的单词(Token),语法分析则根据预定义的文法规则构建抽象语法树(AST),以明确运算优先级和程序结构。掌握编译器技术不仅能深化对编程语言设计、正则表达式、递归、树形数据结构等基础概念的理解,更能培养系统级的工程思维与问题拆解能力。这种“编译器思想”在当今技术实践中价值显著,广泛应用于领域特定语言(D 阅读详情

实验题目

编写识别由下列文法G[E]所定义的表达式的递归下降语法分析器。
E→E+T∣E−T∣TE \rightarrow E+T | E-T | TE→E+T∣E−T∣T
T→T∗F∣T/F∣FT \rightarrow T*F | T/F |FT→T∗F∣T/F∣F
F→(E)∣iF \rightarrow (E) | iF→(E)∣i
输入:含有十进制数或十六进制数的表达式,如:75+(1ah-3*2)+68/2#。
输出:语法正确或语法错误信息。

题目分析

这次实验的重点在于理解递归下降语法分析的代码实现,意在将文法当中的每一种符号利用函数进行封装,然后在符合语法的条件下进行互相调用,完成递归下降语法分析。

难点在于需要对实验1的代码进行微调,达到将含有十进制数或十六进制数的表达式转换为对应的含i的表达式

C++

程序流程图如下:

#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#include <conio.h>
#define digit 1 // 1数字
#define op 2 // +-*/()#
#define Hh 3 // 3Hh
#define AF 4 // 4A-F
#define letter 5 // 5其它字母
using namespace std;

char sym; // 保存当前读入字符 
string line; // 保存读入的一行表达式
int cur; // 表达式字符串中的当前下标
int error; // 错误标志。0:正确; -1:错误
char q; // 指向输入符号串中当前的字符
char word[20]; // 存储当前识别的单词
int state; // 表示所处的状态
int i; // 单词的下标

int E(), E1(), T(), T1(), F(); // 函数声明
char read(string line, int k);
string change_i(string words); // 将含有十进制或十六进制数的表达式转换为用i代替的表达式
int isDigitOrChar(char ch);

int main() {
	ifstream fin("D:/Compile_exp/exp2-test.txt");
	if (!fin.is_open()) {
		cout << "open file error." << endl;
		_getch();
		return -1;
	}

	while (getline(fin, line)) {
		puts("------------------------------------");
		cur = 0;
		error = 0;
		string temp = line;
		line = change_i(line);
		if (line == "-1") {
			cout << temp << " is not a valid express." << endl;
			continue;
		}
		cout << "Output string is: " << line << endl;

		sym = read(line, cur); // 读取第一个字符
		E();

		if (error == -1)
			cout << temp << " is not valid." << endl;
		else if (error == 0) {
			if (cur + 1 < line.size()) { // 未成功匹配提前退出认定为无效
				cout << temp << " is not valid." << endl;
			}
			else {
				cout << temp << " is valid." << endl;
			}
		}
			
	}

	fin.close();
	_getch();

	return 0;
}

// 递归分析函数实现
int E() {  // E->TE'
	T();
	E1();

	return 0;
}

int E1() { // E'->+TE'|-TE'|ε
	if (sym == '+' || sym == '-') {
		cur++;
		sym = read(line, cur);
		T();
		E1();
	}
	else if (sym == '#' || sym == ')')
		return 0;
	else
		error = -1;

	return 0;
}

int T() { // T->FT'
	F();
	T1();

	return 0;
}

int T1() { // T'->*FT'|/FT'|ε
	if (sym == '*' || sym == '/') {
		cur++;
		sym = read(line, cur);
		F();
		T1();
	}
	else {
		if (sym == '#' || sym == ')' || sym == '+' || sym == '-')
			return 0;
		else
			error = -1;
	}
	return 0;
}


int F() { // F->(E)|i
	if (sym == 'i') {
		cur++;
		sym = read(line, cur);
	}
	else if (sym == '(') {
		cur++;
		sym = read(line, cur);
		E();
		if (sym == ')') {
			cur++;
			sym = read(line, cur);
		}
		else
			error = -1;
	}
	else
		error = -1;

	return 0;
}

char read(string line, int k) {
	return line[k];
}

int isDigitOrChar(char ch) {
	if (ch >= 48 && ch <= 57) // 数字
		return digit;
	else if (ch == 72 || ch == 104) // H or h
		return Hh;
	else if ((ch >= 65 && ch <= 70) || (ch >= 97 && ch <= 102)) // 字母A,B,C,D,E,F
		return AF;
	else if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122)) // 除A~F外的其它字母
		return letter;
	else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#')
		return op;
}

// 将含有十进制或十六进制数的表达式转换为用i代替的表达式
string change_i(string words) {
	memset(word, 0, sizeof word);
	state = 0;
	i = 0;
	cout << "Input string is: " << words << endl;

	string result = "";
	int cnt = 0;
	q = words[cnt++];

	while (cnt <= words.size()) {
		// 先判断状态,再判断字符
		switch (state) {
		case 0: // 0状态
			switch (isDigitOrChar(q)) {
			case digit: // 数字
				word[i++] = q;
				state = 2; // 转移到2状态
				break;
			case Hh: // H or h
			case AF: // 字母A,B,C,D,E,F or a,b,c,d,e,f
			case letter: // 字母
				word[i++] = q;
				state = 1;
				break;
			case op: // 操作符
				result += q;
				state = 0;
				break;
			default: // 其它(非法字符 )
				word[i++] = q;
				state = 5;
			}
			break;
		case 1: // 1状态
			switch (isDigitOrChar(q)) {
			case Hh: // 当前状态遇到字母、数字往下读入
			case AF:
			case digit:
			case letter:
				word[i++] = q;
				state = 1;
				break;
			case op: // 读入完毕,识别为标识符
				word[i] = '\0';
				printf("%s is an identifier.\n", word);
				//result += "i";
				memset(word, 0, sizeof word);
				i = 0;
				state = 0;
				break;
			default:
				word[i++] = q;
				state = 5;
			}
			break;
		case 2: // 2状态
			switch (isDigitOrChar(q)) {
			case digit: // 若为数字,不改变状态往下读入
				word[i++] = q;
				state = 2;
				break;
			case Hh: // 若为Hh,转移至状态3
				word[i++] = q;
				state = 3;
				break;
			case AF: // 若为AF,则有可能是16进制,转移至状态4
				word[i++] = q;
				state = 4;
				break;
			case op: // 成功识别为整数
				word[i] = '\0';
				printf("%s is an Integer.\n", word);
				result += "i";
				result += q;
				//cout << result << endl;
				memset(word, 0, sizeof word);
				i = 0;
				state = 0;
				break;
			default:
				word[i++] = q;
				state = 5;
			}
			break;
		case 3: // 3状态
			switch (isDigitOrChar(q)) {
			case op: // 识别为16进制数
				word[i] = '\0';
				printf("%s is a Hex digit.\n", word);
				result += "i";
				result += q;
				//cout << result << endl;
				memset(word, 0, sizeof word);
				i = 0;
				state = 0;
				break;
			default:
				word[i++] = q;
				state = 5;
			}
			break;
		case 4: // 4状态
			switch (isDigitOrChar(q)) {

			case digit: // 若为数字或A~F,仍为状态4,往下读入
			case AF:
				word[i++] = q;
				state = 4;
				break;
			case Hh:
				word[i++] = q;
				state = 3;
				break;
			case op: // 如果16进制没有以h或H结尾,转移至错误状态
				state = 5;
				cnt--;
				break;
			default:
				word[i++] = q;
				state = 5;
			}
			break;
		case 5: // 出错状态
			if (isDigitOrChar(q) == op) { // 若为空格,则识别为非标识符
				word[i] = '\0';
				printf("%s is not an identifier.\n", word);
				memset(word, 0, sizeof word);
				i = 0;
				state = 0;
				result = "-1";
				return result;
			}
			else { // 出错序列还未读取完毕,往下读入
				word[i++] = q;
				q = words[cnt++];
				continue;
			}
			break;
		}
		q = words[cnt++]; // 指针下移(指向输入符号串中的下一个字符)
	}

	return result;
}
编译原理 --- 递归下降分析器 1.在上面这个例子中则是子程序序A先调用子程序B,本程序结束完调用之后再返回来继续调用下一个符号如果下一个符号是终结符的话那就直接进行匹配,不进行调用,匹配完后继续调用下一个符号如果不是的话则调用这个非终结符对应的子程序,并重复步骤 1 1.ADVANCE是一个字程序,作用是输入下一个符号2.SYM则是指向当前输入的单词符号1.一个非终结符的展开就等价于调用这个非终结符对应的语法分析子程序1.一个非终结符对应的子程序就用这个非终结符本身来命名,比如非终结符A的子程序的命名就是A本身2.上面这个设计中的Beg 阅读详情

相关推荐

【编译原理与技术】递归下降语法分析器(C++实现)

目录内容:示例:具体实现:C++代码:运行结果: 内容: 实现以下语法的递归下降分析: 示例: 对于以下代码给出其递归下降语法分析过程: { i=2; while(i<=100) { sum=sum+i; i=i+2; } } 具体实现: 首先对上下文无关文法进行检查,消除左递归和左公共因子,从逻辑上检测避免死循环和低效率处理。 采用每个产生式的左边的文法符号对应一...

Slimshady的博客 1万+

【编译原理】 基于递归下降法实现语法分析器

【编译原理】 基于递归下降法实现语法分析器 【问题描述】 给定以下文法G[E]: E → TE′ E′→ +TE′|ε T → FT′ T′→ *FT′|ε F → a|(E) 用C++或Java编程实现【递归下降法】语法分析器 【输入形式】 一个句子 【输出形式】 若句子语法正确,输出"Syntax analysis is right" 若语法语法错误,输出"Error on syntax analysis" 注:输出不包括引号 【样例输入】 a+a*a 【样例输出】 Syntax analysis

weixin_46283740的博客 1347

从零手搓编译器:Python实现词法分析、语法分析与RISC-V代码生成

编译器是计算机科学的核心基础工具,负责将高级编程语言源代码转换为计算机可执行的机器指令。其核心原理遵循经典的编译流程:词法分析将源代码字符流切分为有意义的词法单元(Token),语法分析则根据预定义的文法规则验证Token序列的合法性并构建抽象语法树(AST),最终通过代码生成器将AST映射为目标平台的汇编指令。理解这一流程对于深入掌握程序运行机制、优化代码性能以及高效使用各类转译和构建工具至关重要。在工程实践中,无论是前端开发中的Babel转译,还是后端JVM的字节码生成,其底层逻辑均与此相通。本文以“手

SailingAptech的专栏 480

编译原理递归下降语法分析器

a.选择测试代码,begin a:=9;x:=2*3;b:=a+xend#,即词法分析器的输入,所示。 b.统计测试程序包含的单词符号,假定关键字、界符、运算符都是一符一种,设计单词符号对应的种别码,如表1 c.词法分析得到的种别码串为1,10,18,11,26,10,18,11,15,11,26,10,18,10,13,10,6,0,此为语法分析的输入。 源程序: //递归下降语法分析程序 #...

qq_43015237的博客 1778

从零实现C语言编译器:词法分析到中间代码生成全解析

编译器作为计算机科学的核心工具,其本质是将高级编程语言翻译成机器可执行代码的确定性规则系统。理解编译原理,关键在于掌握其核心流程:词法分析通过有限自动机将字符流转换为单词流,语法分析利用递归下降法构建抽象语法树,语义分析借助符号表进行类型检查和上下文验证,最终生成与机器无关的中间代码(如三地址码)。这一技术链条不仅支撑着GCC、Clang等工业级编译器的运行,更是理解程序从源代码到可执行文件转换过程的基础。通过实现一个支持int类型、if-else和while语句的MiniC编译器,开发者能够深入体验从正则

weixin_34221112的博客 338

递归下降语法分析器的实现(C++)

递归下降语法分析器是一种基于产生式规则的语法分析方法。它从语法规则的起始符号开始,通过递归地调用自身和对应的产生式规则,将输入的字符串分解为语法规则定义的各个部分,直到达到最终的终结符。在本文中,我们讨论了如何使用C++实现递归下降语法分析器。我们从定义语法规则开始,然后逐步构建了一个简单的递归下降语法分析器。通过这个例子,我们可以看到递归下降语法分析器的工作原理,并了解如何使用C++来实现它。递归下降语法分析器是一种常见的语法分析方法,它可以用于解析各种编程语言中的语法结构。

TechBurst的博客 1068

如何把一副普通眼镜变成能“记住“你看到过的 AI 智能眼镜:OpenGlass 25 元 DIY 指南

在展会、展会或者任何场合,你见过的人、路过的牌子,转头就忘。OpenGlass 是一个 DIY 的 AI 智能眼镜开源项目:用不到 25 美元的现成零件,把一副普通眼镜变成持续拍摄第一视角画面的摄像头,让本地视觉模型把画面"读"成文字,再用语音回答你"刚才看到了什么"。本文按仓库现状,把买件、烧录、配网到连上蓝牙的完整流程走一遍。 ## 戴上之后能做什么 配对成功后,设备每 5 秒拍一帧,把画

gitblog_00714的博客 833

从零配置EtherCAT IGH主站:手把手教你处理内核版本与实时性优化的那些坑

本文详细指导如何从零配置EtherCAT IGH主站,涵盖内核版本适配、实时性优化及常见问题解决方案。通过精确匹配内核头文件、应用实时补丁和优化网卡驱动,帮助开发者实现微秒级响应,适用于工业自动化、机器人控制等高精度场景。

weixin_30790841的博客 382

TinyExpr完整指南:如何在C项目中快速集成数学表达式解析器

**TinyExpr**是一个轻量级、高性能的C语言数学表达式解析器,它能够在你的项目中快速实现复杂的数学表达式求值功能。这个完整的指南将带你了解如何在C项目中轻松集成这个强大的数学表达式解析器工具。无论你是需要处理用户输入的数学公式,还是要在嵌入式系统中实现表达式计算,TinyExpr都能提供简洁高效的解决方案。😊 ## 🔍 什么是TinyExpr数学表达式解析器? TinyExpr是一

gitblog_00014的博客 545

HEVC/VVC中R-Lambda码率控制算法原理

文章目录1. 比特分配1.1 GOP级比特分配1.2 帧级比特分配1.3 LCU级比特分配2. 码率控制2.1 λ的计算和更新2.2 参数QP的确定 VVC中码率控制算法沿用了HEVC中经典的R-λ码率控制模型,R-λ由中科大的李斌博士提出(详情参考JCTVC-K0103)。R-λ模型的基础为视频编码中 R(比特 bpp)和 D(失真 MSE)之间的双曲线模型,即 D(R)=CR−KD(R) = ...

Aidoneus_y 6136

Cube.js 安装避坑指南:从零到一键启动

本文是一份详细的Cube.js安装避坑指南,旨在帮助开发者从零开始顺利启动Cube.js。文章重点强调了安装前的环境准备,包括Node.js版本、包管理工具和项目路径等关键“地基”,并深入解析了使用npx安装的优势、数据库类型选择以及数据库连接配置的核心步骤与常见陷阱,确保您能高效完成安装并成功启动服务。

weixin_29218509的博客 429

Egg 框架内置基础对象完全指南:Application、Context、Controller、Service、Helper、Config、Logger 与订阅模型

本篇指南系统梳理 Egg 框架内置的九类基础对象:从 Koa 继承的 `Application`、`Context`、`Request`、`Response`,以及框架扩展的 `Controller`、`Service`、`Helper`、`Config`、`Logger` 与 `Subscription` 订阅模型。文中不仅给出每一类对象的作用域、生命周期与获取方式,还结合当前仓库源码揭示其底层

gitblog_00615的博客 858

从想法到零件:手把手拆解一个汽车功能如何从PRD写到SSTS和CTS

本文详细拆解了汽车电子需求从市场文档(MRD)到零部件技术规范(CTS)的完整流程,以雨天自动关窗功能为例,展示了PRD、SSTS和CTS的编写要点与交互设计。文章重点解析了系统分解的艺术和零部件落地的精确参数要求,为汽车电子工程师提供了从概念到实现的全流程实践指南。

weixin_30300225的博客 480

TinyExpr:5分钟掌握C语言轻量级表达式解析库

你是否曾经需要在C/C++项目中动态计算数学表达式,但又不想引入庞大的数学库?TinyExpr正是为你量身打造的解决方案。这个超轻量级的递归下降解析器将表达式求值功能压缩到仅两个文件,让你轻松实现运行时数学计算。 ## 为什么选择TinyExpr? 在嵌入式系统、游戏开发、科学计算或任何需要动态表达式求值的场景中,TinyExpr提供了完美的平衡点。它不像传统数学库那样臃肿,却能处理复杂的数学

gitblog_01004的博客 1145

CentOS7下NFS共享报错RPC问题的3种解决方案(含防火墙配置详解)

本文详细解析了CentOS7下NFS共享报错RPC问题的3种解决方案,包括防火墙配置详解。从基础连通性检查到RPC服务状态验证,再到精准开放必要端口和SELinux集成,提供全面的排查与解决指南,帮助用户快速解决'No route to host'等常见问题。

weixin_29274969的博客 452

【推荐100个unity插件】unity易于使用模块化设计的天空、体积云和天气系统——Enviro 3

Enviro 3是一款功能强大的Unity天空与天气系统插件,提供动态天空、体积云、天气模拟等丰富功能。安装时需将预制体拖入场景并配置主相机,URP支持需激活深度纹理和添加渲染特性。模块化设计允许自由添加/移除时间、光照、雾效等模块,并通过API控制参数。推荐配合色调映射(如ACES模式)获得最佳视觉效果。插件支持季节、温湿度模拟及闪电风暴等特效,适用于需要逼真环境渲染的Unity项目。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2092

TinyExpr项目实战:构建交互式数学表达式计算器

TinyExpr是一款轻量级的数学表达式解析和计算引擎,采用递归下降解析器设计,能在运行时高效评估数学表达式。它以C99标准编写,无任何依赖项,仅需两个文件(tinyexpr.c和tinyexpr.h)即可集成到你的项目中,为应用添加动态数学计算能力。 ## ✨ TinyExpr核心优势 TinyExpr之所以成为开发者的理想选择,源于其独特的功能组合: - **极致精简**:单文件设计,无

gitblog_01054的博客 1039

【PINN物理信息网络】基于PINN物理信息网络求解泊松方程(python)

【PINN物理信息网络】基于PINN物理信息网络求解泊松方程(python)

k8291121的博客 2811

如何快速掌握TinyExpr:3分钟学会C语言数学表达式解析库

TinyExpr是一个轻量级的递归下降表达式解析器和求值引擎,专门用于在C语言项目中实时解析和计算数学表达式。这个开源数学表达式解析库让你无需引入复杂依赖,就能为应用程序添加强大的数学计算能力。无论你是嵌入式开发者、游戏程序员还是需要动态公式计算的应用开发者,TinyExpr都能以最小的代码开销提供完整的数学表达式处理功能。 ## 项目亮点与特色 🚀 TinyExpr以其极简设计赢得了众多开

gitblog_00799的博客 1074

EPLAN 电气制图(六):结构盒与设备管理器核心概念(基础知识选看)

结构盒是 EPLAN 中用于标识元件安装位置的逻辑容器,非实际设备或黑盒,仅用于原理图中划分功能区域或物理位置(如 “柜内”“柜外”)。标识符设置:在 “显示设备标识符” 中输入位置代号(如 “+ 柜外”),完整格式为 “= 高层代号 + 位置代号”;筛选与定位:通过 “筛选器” 按类别(如电机、接触器)快速查找设备,右键 “转到(图形)” 可高亮定位图纸中的元件;设备保护:重要设备可启用保护(【项目数据】→【设备】→【启用设备保护】),防止误删除(显示橙色圆圈标记)。

电工 1056

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

TinyExpr终极指南:用C语言实现高效的数学表达式解析与求值 [特殊字符]

在嵌入式系统、科学计算和游戏开发中,经常需要在运行时动态解析和计算数学表达式。传统方法要么过于笨重,要么功能有限。TinyExpr的出现完美解决了这一痛点——这是一个仅需两个文件就能集成到任何C项目中的轻量级数学表达式解析器,支持标准运算符、数学函数和运行时变量绑定。本文将深入解析TinyExpr的核心能力、实战应用和性能优化技巧,帮助开发者快速掌握这个强大的工具。 ## 🔍 核心能力解析:T

gitblog_00737的博客 629

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

TinyExpr核心API详解:te_interp、te_compile、te_eval和te_free函数完全解析

TinyExpr是一款轻量级的递归下降表达式解析器、编译器和数学表达式求值引擎,它提供了四个核心API函数——te_interp、te_compile、te_eval和te_free,这些函数构成了表达式解析和求值的完整流程。本文将详细解析这四个函数的功能特性、使用方法和最佳实践,帮助开发者快速掌握TinyExpr的核心用法。 ## 一、一站式表达式求值:te_interp函数 te_inte

gitblog_00454的博客 510

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

OpenToonz 快速上手:10 分钟做出你的第一段动画

10 分钟后,你会在 OpenToonz 里让一个小球跳起来,并导出成一个视频文件。全程只需要画一个圆、移两下位置、加一个滤镜。下面是完整走法。 ## 🔧 环境准备 如果你手上还没有 OpenToonz,克隆仓库拿到源码: ```bash git clone https://gitcode.com/GitHub_Trending/op/opentoonz ``` 验证方法:打开项目里的

gitblog_00508的博客 316

探索TinyExpr:小巧而强大的数学表达式解析器

探索TinyExpr:小巧而强大的数学表达式解析器 项目地址:https://gitcode.com/gh_mirrors/ti/tinyexpr 在编程中,有时我们希望在运行时能够动态地计算数学表达式。这就是TinyExpr的用武之地——一个简洁且高效的开源库,它允许您轻松地在C语言项目中添加对数学表达式的解析和评估功能。 项目简介 TinyExpr是一个轻量级的递归下降解析器,设计用于解析并执...

gitblog_00076的博客 1493

从计算器到编译器:深入理解表达式求值,手写一个迷你解释器

本文深入探讨了表达式求值的核心原理,从中缀表达式到后缀表达式的转换,详细介绍了如何手写一个迷你解释器。通过词法分析、语法分析及解释器实现的完整流程,帮助读者理解计算机如何处理算术表达式,并提供了代码示例和扩展功能的实现方法。

weixin_30542079的博客 373

语法与语义实战:用Python手写科学公式解析器

程序开发中,语法错误(如SyntaxError、SQL syntax错误)是高频问题,但深入理解语法与语义的差异才能真正定位问题。语法决定文本结构是否合法,语义决定结构在运行时能否产生有效结果。本文以科学公式为切入点,讲解分词、递归下降语法分析、AST构建与语义求值等核心原理,并给出一个可运行的Python公式解析器实现。通过解析器,开发者可以掌握配置解析、规则引擎和DSL设计的基础能力。同时,文章结合实际场景梳理Python、MySQL、PostgreSQL、Nginx常见报错的排查思路,帮助读者建立从文

cigang4063的博客 481
上一篇: 【乌蒙磅礴走泥丸】天桥赛后回忆录
下一篇: 【数据结构】红黑树学习笔记
CodeSlogan
博客等级 码龄6年 4227粉丝 130原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeSlogan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值