西电 程序设计基础课程设计 作业

当时做的程序设计课程的作业. 一共五题, 以报告的形式提交.

质量应该比较高(高傲).

完整内容在这里

高精度计算

问题描述

涉及知识点: 数组, 流程控制, 函数等

要求:

用整型数组表示10进制大整数(超过 2 32 2^{32} 232 的整数), 数组的每个元素存储大整数的一位数字, 实现大整数的加减法.

问题分析

结构设计

可将高精度整数写成一个类.

成员变量有:

int a[MAXN], len;
bool negative;

其中, 数组a用来存储大整数的一个数位, a[1]为个位上的数字, a[2]为十位上的数字… len表示数字的位数, negative 表示是否为负数.

算法设计

绝对值比较大小

先判断两数的位数, 位数小的数小.

位数不相等, 再从高位到低位判断数值的大小, 数值小的数小.

数值都相等, 则两数相等.

代码中的abs_lower()即为绝对值比较大小的具体实现.

无符号加法(绝对值相加)

设两加数为 x , y x, y x,y

先创建一个高精度整数对象ans. 将ans.len设为max(x.len, y.len) + 1. 因为结果的位数不会超过这个值.

从个位开始, 两个数的对应位数相加存入ans的对应位置. 如果和大于 10 10 10, 则进位, 即ans的下一位 + 1 +1 +1, 然后这一位对 10 10 10取模.

最后考虑是否ans.len是不是大了(因为一开始设置的是可能达到的最大值), 依次判断前面是不是 0 0 0, 如果是, 则减小len, 如果不是, 则说明len正好.

注意当len=1ans=0时, 不应该继续减小len, 且要设置negative=0. 即这个数是 0 0 0, 0 0 0的位数是 1 1 1, − 0 -0 0应该表示为 0 0 0.

返回ans.

代码中的abs_plus()即为无符号加法的具体实现.

无符号减法(绝对值相减)

设被减数与减数分别为 x , y x, y x,y.

创建高精度整数对象ans.

先判断正负号, 利用绝对值比较大小. 如果 x < y x < y x<y, 那么设置ans.negative=1, 数值为 y − x y-x yx的数值.

所以不妨假设 x > y x > y x>y, 具体实现和加法类似, 先设ans.len为可能的最大值, 即max(x.len, y.len), 从低位到高位计算各个数位, 注意借位即可.

和加法一样, 最后处理一下ans.len以及ans.negative, 然后返回ans.

代码中的abs_minus()即位无符号减法的具体实现.

有符号的加减法

有符号的加减法可以通过对两参数的符号分类讨论, 进而转化为无符号加减法.

加法

设两加数为 x , y x, y x,y, 其绝对值为 ∣ x ∣ , ∣ y ∣ |x|, |y| x,y

x , y x, y x,y符号相同, 则和的数值 ∣ x ∣ + ∣ y ∣ |x|+|y| x+y, 符号为加数的符号;

x , y x, y x,y符号不同, 则加法转化为绝对值的减法:

x x x为负, 则结果为 ∣ y ∣ − ∣ x ∣ |y|-|x| yx; 若 y y y为负, 则结果为 ∣ x ∣ − ∣ y ∣ |x|-|y| xy.

代码中重载运算符 + 即为加法的具体实现.

减法

设被减数和减数分别为 x , y x, y x,y

x , y x, y x,y符号相同, 若参数符号为正, 则差为 ∣ x ∣ − ∣ y ∣ |x|-|y| xy; 若为负, 则差为绝对值相减后的相反数;

x , y x, y x,y符号不同, 则转化为绝对值加法, 符号与 x x x一致.

代码中重载运算符 - 即为减法的具体实现.

其他运算符的重载

比较运算符基于已重载的 <, 自增自减基于已重载的 +-.

重载的原理比较简单, 这里不再赘述.

完整代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

class BigInt {
private:
	static const int MAXN = 100;
	int a[MAXN], len;	// a中每一位存数字, len为大整数的长度
	bool negative;		// 是否是负数
	bool abs_lower(const BigInt &x, const BigInt &y) const;
	BigInt abs_plus(const BigInt &x, const BigInt &y) const;
	BigInt abs_minus(const BigInt &x, const BigInt &y) const;
	void adjust();
public:
	BigInt(const int x = 0);
	BigInt(const char s[]);
	bool operator < (const BigInt &y) const;
	bool operator == (const BigInt &y) const;
	bool operator != (const BigInt &y) const;
	bool operator >= (const BigInt &y) const;
	bool operator > (const BigInt &y) const;
	bool operator <= (const BigInt &y) const;
	BigInt operator += (const BigInt &y);
	BigInt operator -= (const BigInt &y);
	BigInt operator ++ ();
	BigInt operator -- ();
	BigInt operator ++ (int);
	BigInt operator -- (int);
	BigInt operator + (const BigInt &y) const;
	BigInt operator - (const BigInt &y) const;
	BigInt operator = (const BigInt &y);
	BigInt operator = (const int &y);
	BigInt operator = (const char s[]);
	BigInt operator - () const;
	void print();
};

/********************************
/ 构造函数, int转大整数
/ para x: 需要转成大整数的int型
********************************/
BigInt::BigInt(const int x) {
	memset(a, 0, sizeof(a));
	len = 0;
	negative = x < 0;
	int tmp = abs(x);
	do {
		a[++len] = tmp % 10;
		tmp /= 10;
	} while(tmp);
}

/********************************
/ 构造函数, string转大整数
/ para s: 需要转成大整数的字符串
********************************/
BigInt::BigInt(const char s[]) {
	memset(a, 0, sizeof(a));
	negative = s[0] == '-';
	len = strlen(s) - negative;
	for (int i = 0; i < len; i++)
		a[len - i] = s[i + negative] - '0';
	adjust();
}

/********************************
/ 重载 =, 同类型直接赋值
********************************/
BigInt BigInt::operator = (const BigInt &y) {
	len = y.len;
	negative = y.negative;
	memcpy(a, y.a, sizeof(a));
	return *this;
}

/********************************
/ 重载 =, 通过构造函数实现int转BigInt
********************************/
BigInt BigInt::operator = (const int &y) {
	return *this = BigInt(y);
}

/********************************
/ 重载 =, 通过构造函数实现string转BigInt
********************************/
BigInt BigInt::operator = (const char s[]) {
	return *this = BigInt(s);
}

/********************************
/ 重载 <
/ return: 是否小于 y
********************************/
bool BigInt::operator < (const BigInt &y) const {
	if (negative == y.negative)
		return negative ^ abs_lower(*this, y);
	else
		return negative;
}

/********************************
/ 重载 ==
/ return: 是否等于 y
********************************/
bool BigInt::operator == (const BigInt &y) const {
	if (len == y.len) {
		for (int i = 1; i <= len; i++)
			if (a[i] != y.a[i])
				return false;
		return true;
	}
	return false;
}

/********************************
/ 重载 !=
/ return: 是否不等于 y
********************************/
bool BigInt::operator != (const BigInt &y) const {
	return !(*this == y);
}

/********************************
/ 重载 >=
/ return: 是否不小于 y
********************************/
bool BigInt::operator >= (const BigInt &y) const {
	return !(*this < y);
}

/********************************
/ 重载 >
/ return: 是否大于 y
********************************/
bool BigInt::operator > (const BigInt &y) const {
	return *this >= y && *this != y;
}

/********************************
/ 重载 <=
/ return: 是否不大于 y
********************************/
bool BigInt::operator <= (const BigInt &y) const {
	return !(*this > y);
}

/********************************
/ 重载 +=
/ return: 加上y后的值
********************************/
BigInt BigInt::operator += (const BigInt &y) {
	return *this = (*this + y);
}

/********************************
/ 重载 -=
/ return: 减去y后的值
********************************/
BigInt BigInt::operator -= (const BigInt &y) {
	return *this = (*this - y);
}

/********************************
/ 重载前置 ++
/ return: +1 后的值
********************************/
BigInt BigInt::operator ++ () {
	return *this = (*this + BigInt(1));
}

/********************************
/ 重载前置 --
/ return: -1 后的值
********************************/
BigInt BigInt::operator -- () {
	return *this = (*this - BigInt(1));
}

/********************************
/ 重载后置 ++
/ return: 原值
********************************/
BigInt BigInt::operator ++ (int) {
	BigInt tmp = *this;
	++(*this);
	return tmp;
}

/********************************
/ 重载后置 --
/ return: 原值
********************************/
BigInt BigInt::operator -- (int) {
	BigInt tmp = *this;
	--(*this);
	return tmp;
}

/********************************
/ 重载 +
/ return: 加上y之后的值
********************************/
BigInt BigInt::operator + (const BigInt &y) const {
	if (negative == y.negative) {
		BigInt ans = abs_plus(*this, y);
		ans.negative = negative;
		return ans;
	}
	else
		return negative ? abs_minus(y, *this) : abs_minus(*this, y);
}

/********************************
/ 重载 -
/ return: 大整数减去y之后的值
********************************/
BigInt BigInt::operator - (const BigInt &y) const {
	if (negative == y.negative) {
		BigInt ans = abs_minus(*this, y);
		ans.negative ^= negative;
		return ans;
	}
	else {
		BigInt ans = abs_plus(*this, y);
		ans.negative = negative;
		return ans;
	}
}

/********************************
/ 重载前置负号, 取相反数
/ return: 相反数
********************************/
BigInt BigInt::operator - () const {
	BigInt ans = *this;
	ans.negative ^= 1;
	ans.adjust();
	return ans;
}

/********************************
/ 输出大整数
********************************/
void BigInt::print() {
	if (negative)
		printf("-");
	for (int i = len; i; i--)
		printf("%d", a[i]);
}

/********************************
/ 判断两个大整数的绝对值大小
/ para x, y: 两个大整数
/ return: |x| 是否小于 |y|
********************************/
bool BigInt::abs_lower(const BigInt &x, const BigInt &y) const {
	if(x.len == y.len) {
		for(int i = x.len; i >= 1; i--)
			if(x.a[i] < y.a[i])
				return true;
			else if (x.a[i] > y.a[i])
				return false;
		return false;
	}
	return x.len < y.len;
}

/********************************
/ 两大整数的绝对值相加
/ para x, y: 两大整数
/ return: 大整数|x| + |y|, 符号为正
********************************/
BigInt BigInt::abs_plus(const BigInt &x, const BigInt &y) const {
	BigInt ans;
	ans.len = max(x.len, y.len) + 1;
	for(int i = 1; i <= ans.len; i++) {
		ans.a[i] += x.a[i] + y.a[i];
		ans.a[i+1] = ans.a[i] / 10;
		ans.a[i] %= 10;
	}
	ans.adjust();
	return ans;
}

/********************************
/ 两大整数的绝对值相减
/ para x, y: 两大整数
/ return: 大整数|x| - |y|, 有符号
********************************/
BigInt BigInt::abs_minus(const BigInt &x, const BigInt &y) const {
	if(abs_lower(x, y)) {
		BigInt ans = abs_minus(y, *this);
		ans.negative = 1;
		return ans;
	}
	BigInt ans;
	ans.len = max(x.len, y.len);
	for(int i = 1; i <= ans.len; i++) {
		if(x.a[i] < y.a[i]) {
			ans.a[i + 1]--;
			ans.a[i] += 10;
		}
		ans.a[i] += x.a[i] - y.a[i];
	}
	ans.adjust();
	return ans;
}

/********************************
/ 调整len的值, 用于加减法运算中
********************************/
void BigInt::adjust() {
	while(len > 1 && !a[len])
		len--;
	if (len == 1 && !a[1])
		negative = 0;
}

简单数据结构-堆栈模拟

问题描述

涉及知识点: 内存管理, 结构体定义, 基本数据结构

要求:

编写一个程序模拟堆栈, 要求能够模拟, 入栈, 出栈, 返回栈顶元素等基本操作. 栈中元素可用整数代替. 不能使用C++模板库预定义的类型. 程序运行中可输入多组入栈, 出栈操作, 每次操作后展示栈中元素.

问题分析

结构设计

考虑到栈的可拓展性, 可将其写成模板类.

首先定义一个模板节点, 除了存储数据意外, 还存储一个指针. 这个指针指向栈中的下一个元素.

其次是栈类, 成员变量有数据的栈顶指针Node<T> *head, 以及栈中的元素个数(栈的大小)sz.

算法设计

初始化栈的大小为 0 0 0, 栈顶指针为空, 表示空栈.

push

新建节点, 将该节点的值设为输入值, 指针指向当前栈顶元素.

将栈顶指针指向新建的节点.

代码中的push()即push的具体实现

top

直接调用栈顶指针head, 返回其所指的元素的值.

代码中的top()即top的具体实现

pop

栈顶元素的nxt指针指向的是倒数第二个元素. 所以将栈顶指针指向该元素, 并将栈顶删除.

代码中的pop()即pop的具体实现

其他函数

根据实际问题, 实现了其他辅助性的函数.

这些函数比较简单, 不再赘述.

完整代码

完整内容在这里

位图图像文件缩放

问题描述

涉及知识点: 文件读写, 结构体定义, 内存管理, 基本图像处理算法, 命令行参数

要求:

编写一个程序, 可以在命令行输入参数, 完成指定文件的缩放, 并存储到新文件, 命令行参数如下

zoom file1.bmp 200 file2.bmp

第一个参数为可执行程序名称, 第二个参数为原始图像文件名, 第三个参数为缩放比例(百分比), 第四个参数为新文件名

问题分析

结构设计

位图结构

位图文件由三部分组成: 文件头 + 位图信息 + 位图像素数据

1, 位图文件头. 位图文件头主要用于识别位图文件. 以下是位图文件头结构的定义:

typedef struct tagBITMAPFILEHEADER { // bmfh
    WORD    bfType;
    DWORD   bfSize;
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;
} BITMAPFILEHEADER;

其中的bfType值应该是"BM" (0x4d42) , 标志该文件是位图文件. bfSize的值是位图文件的大小.

2, 位图信息中所记录的值用于分配内存, 设置调色板信息, 读取像素值等.
以下是位图信息结构的定义:

typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER    bmiHeader;
    RGBQUAD             bmiColors[1];
} BITMAPINFO;

可见位图信息也是由两部分组成的: 位图信息头 + 颜色表

2.1位图信息头. 位图信息头包含了单个像素所用字节数以及描述颜色的格式, 此外还包括位图的宽度, 高度, 目标设备的位平面数, 图像的压缩格式. 以下是位图信息头结构的定义:

typedef struct tagBITMAPINFOHEADER{ // bmih
    DWORD  biSize;
    LONG   biWidth;
    LONG   biHeight;
    WORD   biPlanes;
    WORD   biBitCount
    DWORD  biCompression;
    DWORD  biSizeImage;
    LONG   biXPelsPerMeter;
    LONG   biYPelsPerMeter;
    DWORD  biClrUsed;
    DWORD  biClrImportant;
} BITMAPINFOHEADER;

下表是对结构体当中各个成员的说明:

结构成员说 明
biSize结构BITMAPINFOHEADER的字节数, 即sizeof(BITMAPINFOHEADER)*
biWidth以像素为单位的图像宽度*
biHeight以像素为单位的图像长度*
biplanes目标设备的位平面数
biBitCount每个像素的位数* (1)
biCompression图像的压缩格式 (这个值几乎总是为0)
biSizeImage以字节为单位的图像数据的大小 (对BI_RGB压缩方式而言)
biXPelsPermeter水平方向上的每米的像素个数
biYpelsPerMeter垂直方向上的每米的像素个数
biClrused调色板中实际使用的颜色数 (2)
biClrImportant现实位图时必须的颜色数 (3)

说明: *是需要加以注意的部分, 因为它们是我们在进行位图操作时经常参考的变量

(1) 对于每个像素的字节数, 分别有一下意义:

  • 0, 用在JPEG格式中
  • 1, 单色图, 调色板中含有两种颜色, 也就是我们通常说的黑白图片
  • 4, 16色图
  • 8, 256色图, 通常说的灰度图
  • 16, 64K图, 一般没有调色板, 图像数据中每两个字节表示一个像素, 5个或6个位表示一个RGB分量
  • 24, 16M真彩色图, 一般没有调色板, 图像数据中每3个字节表示一个像素, 每个字节表示一个RGB分量
  • 32, 4G真彩色, 一般没有调色板, 每4个字节表示一个像素, 相对24位真彩图而言, 加入了一个透明度, 即RGBA模式

(2) 这个值通常为0, 表示使用biBitCount确定的全部颜色, 例外是使用的颜色树木小于制定的颜色深度的颜色数目的最大值.

(3) 这个值通常为0, 表示所有的颜色都是必需的

2.2颜色表. 颜色表一般是针对16位一下的图像而设置的, 对于16位和16位以上的图像, 由于其位图像素数据中直接对对应像素的RGB(A)颜色进行描述, 因而省却了调色板. 而对于16位一下的图像, 由于其位图像素数据中记录的只是调色板索引值, 因而需要根据这个索引到调色板去取得相应的RGB(A)颜色. 颜色表的作用就是创建调色板.

颜色表是由颜色表项组成的, 颜色表项结构的定义如下:

typedef struct tagRGBQUAD { // rgbq
    BYTE    rgbBlue;
    BYTE    rgbGreen;
    BYTE    rgbRed;
    BYTE    rgbReserved;
} RGBQUAD;

其中需要注意的问题是, RGBQUAD结构中的颜色顺序是BGR, 而不是平常的RGB.

3, 位图数据. 最后, 在位图文件头, 位图信息头, 位图颜色表之后, 便是位图的主体部分: 位图数据. 根据不同的位图, 位图数据所占据的字节数也是不同的, 比如, 对于8位位图, 每个字节代表了一个像素, 对于16位位图, 每两个字节代表了一个像素, 对于24位位图, 每三个字节代表了一个像素, 对于32位位图, 每四个字节代表了一个像素.

算法设计

由于比 8 位更小的位深一个像素不到一个字节, 处理需完全展开字节, 较为麻烦, 练习只处理 8 位以上的位图.

头文件windows.h中定义了与位图有关的结构体, 直接拿来用即可.

输入输出

根据位图定义进行读入和输出.

需要注意的是, 八位及以下的位图具有调色板, 需要读入, 且调色板大小为 256 × 4 256 \times 4 256×4.

输入和输出较为简单, 不再赘述.

临近插值法缩放位图

由缩放比例 r r r和缩放后的坐标 ( x , y ) (x, y) (x,y), 可以得到原图中对应坐标 ( x / r , y / r ) (x/r, y/r) (x/r,y/r). 其中, / 和c中的一致, 当 x ( y ) > 0 , r > 0 x(y)>0, r>0 x(y)>0,r>0时取下整.

用原图中对应坐标像素填充缩放后的坐标, 这种简单的缩放方法成为临近插值法.

具体实现也很简单. 需要注意的是, 不同位深的位图存储一个像素的数据大小是不同的, 对于bitCount位深, 每bitCount/8个字节代表一个像素. 在赋值的过程中需注意. 利用memcopy函数可以方便进行复制.

代码中scale()即为缩放的具体实现.

完整代码

完整内容在这里

简单文件数据库-模拟图书馆管理系统

问题描述

涉及知识点: 文件读写, 内存管理, 结构体定义, 基本数据结构, 高级格式化输入输出

要求:

编写一个程序模拟图书管理系统. 用户分为管理员和读者两类, 分别显示不同文本格式菜单, 通过菜单项对应数字进行选择. 读者菜单包括借书, 还书, 查询等功能. 管理员菜单包括图书和读者信息录入, 修改和删除. 图书信息至少应包括: 编号, 书名, 数量, 读者信息至少应包括: 编号, 姓名, 所借图书. 可根据图书名称或编号进行图书信息查询, 可查询某本书现在被哪些读者借走.
命令行参数如下:

L i b s i m   − a ( − u )   x x x x Libsim\ -a(-u)\ xxxx Libsim a(u) xxxx

第一个参数为可执行程序名称; 第二个参数为用户身份, -a表示管理员, -u表示读者; 第三个参数为用户名

问题分析

结构设计

参考数据库的思想, 创建两张表, 第一张为books, 保存图书信息; 第二张为info, 保存借阅信息.

books

图书信息包含以下内容:

图书编号(ID), 书名(Name), 总量(Amount), 剩余量(Stock).

info

借阅信息包含一下内容:

借阅者用户名(Borrower), 图书编号(ID).

算法设计

图书可写成一个类, 实现借阅, 归还等函数.

借阅信息可写成结构体.

重载输入<<, 输出>>符号, 使用文件流的方式读写.

读者和管理员都是用户, 所以可以写三个类, 其中用户User是父类, 读者Reader和管理员Admin继承User. 这样可以使用多态, 增强可拓展性和可读性, 同时减少重复代码, 降低工作量.

用户

读者和管理员都共同具有的属性以及共同进行的操作可以写在User里, 包括用户名, 查询所有图书, 搜索图书, 查询图书借阅情况等.

读者

读者比父类用户多一个成员变量borrowed_books, 类型为multiset<int>保存借阅了哪些图书.

读者还有更多的操作: 查看已借阅图书, 借书, 还书等.

管理员

管理员具有更多的操作: 对图书以及借阅信息的增加, 删除, 修改.

其中, 对图书的增加, 删除, 修改要注意是否有书被借出. 如果有, 则不应该进行非法的修改.

对借阅信息的增加, 删除, 修改可以通过实例化对应读者Reader, 调用Reader的借书, 还书等函数实现.

这种写法不仅化减小了工作量, 而且具有很强的实际意义: 管理员能够管理所有用户, 能够进入用户账号进行相应操作.


操作的实现基本上都是遍历数据, 进行相应的修改. 比较简单, 不再赘述.

完整代码

完整内容在这里

  • 3
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计是高等教育阶段学生在完成学业前所进行的一项重要学术任务,旨在检验学生通过学习所获得的知识、技能以及对特定领域的深刻理解能力。这项任务通常要求学生运用所学专业知识,通过独立研究和创新,完成一个实际问题的解决方案或者开展一项有价值的项目。 首先,毕业设计的选择通常由学生根据个人兴趣、专业方向以及实际需求来确定。学生需要在导师的指导下明确研究目标、问题陈述,确立研究的范围和深度。毕业设计可以包括文献综述、需求分析、方案设计、实施与测试等多个阶段,以确保整个过程的科学性和系统性。 其次,毕业设计的完成通常需要学生具备一定的独立思考和解决问题的能力。在研究过程中,学生可能需要采用各种研究方法,如实验、调查、案例分析等,以获取必要的数据和信息。通过这些活动,学生能够培养扎实的专业技能,提升解决实际问题的实际能力。 第三,毕业设计的撰写是整个过程的重要组成部分。学生需要将研究过程、方法、结果以及结论等详细记录在毕业论文中,以展示其研究的全貌和成果。同时,撰写毕业设计还有助于提高学生的学术写作水平,培养清晰、逻辑的表达能力。 最后,毕业设计的评价通常由导师和相关专业人士进行。评价标准包括研究的创新性、实用性、方法的科学性以及论文的质量等方面。学生在毕业设计中获得的成绩也将直接影响其最终的学业成绩和学位授予。 总的来说,毕业设计是高等教育中的一项重要环节,通过此过程,学生不仅能够巩固所学知识,还能培养独立思考和解决问题的能力,为将来的职业发展奠定坚实的基础
西电是指西安电子科技大学,是国内著名的理工科院校。电子技术基础课程设计是该校计算机学院的一门必修课程,CSDN是指CSDN社区,是国内最大的IT技术社区之一。 西电电子技术基础课程设计是为了培养学生在电子技术领域的能力和素养而设计的。在这门课程中,学生将通过理论学习和实践操作来了解和掌握电子技术的基本原理和基础知识。课程设计是该课程的一部分,旨在让学生通过实际项目来巩固和应用所学的理论知识。 在这门课程的课程设计中,学生将从实际应用的角度出发,选择一个具体项目进行设计与实现。项目的选题可以是学院或企业提供的实际问题,也可以是学生自己感兴趣的主题。通过选题、需求分析、系统设计、算法实现等环节,学生将逐步完成一个完整的电子技术应用方案。 CSDN作为国内最大的IT技术社区之一,在西电的电子技术基础课程设计中也起到了重要的作用。学生可以通过CSDN社区获取相关的技术文档、问答、教程等资源,与其他开发者进行交流与讨论。在项目实现过程中,CSDN社区也提供了一个展示和分享成果的平台,学生可以将自己的项目经验和心得发布在社区上,与其他开发者共同进步。 总之,西电电子技术基础课程设计通过实际项目的设计与实现,培养学生在电子技术领域的能力和素养。而CSDN社区则为学生提供了丰富的技术资源和交流平台,使学生能够更好地学习和应用电子技术知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值