IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> gcc背后的库函数和opencv的相关编辑 -> 正文阅读

[人工智能]gcc背后的库函数和opencv的相关编辑

生成静态库和动态库文件

在桌面上建立目录,导航到目录,在建立三个文件,hello.c main.c hello.h
mkdir a ,cd a, touch hello.c main.c hello.h
分别编辑程序

//hello.c
#include<stdio.h>
void hello(const char *name)
{
printf("Hello %s!\n",name);
}
//main.c
#include <stdio.h>
#include "hello.h"
int main()
{
hello("everyone");
return 0;
}
//hello.h
#ifndef _HELLO_H_
#define _HELLO_H_
#include<stdio.h>
void hello(const char *name)#endif

建立hello.o文件

shu@shu-virtual-machine:~$ cd ~/桌面/a
shu@shu-virtual-machine:~/桌面/a$ touch hello.c
shu@shu-virtual-machine:~/桌面/a$ gedit hello.c
shu@shu-virtual-machine:~/桌面/a$ gcc -c hello.c
shu@shu-virtual-machine:~/桌面/a$ ls
hello.c  hello.h  hello.o  main.c

有了hello.o目标文件,之后可以创建静态库。
用ar -crv libmyhello.a hello.o 函数创建静态库,静态库函数前缀为lib,后缀为.a中间文件名,后面为目标文件。

shu@shu-virtual-machine:~/桌面/a$ ar -crv libmyhello.a hello.o
a - hello.o
shu@shu-virtual-machine:~/桌面/a$ ls
hello.c  hello.h  hello.o  libmyhello.a  main.c
shu@shu-virtual-machine:~/桌面/a$ 
//静态库文件libmyhello.a

在程序中使用静态库,先生成main.o目标文件

shu@shu-virtual-machine:~/桌面/a$ gcc -c main.c
shu@shu-virtual-machine:~/桌面/a$ ls
hello.c  hello.h  hello.o  libmyhello.a  main.c  main.o
shu@shu-virtual-machine:~/桌面/a$ 

后面建立可执行文件

shu@shu-virtual-machine:~/桌面/a$ gcc -o 1  main.o libmyhello.a
shu@shu-virtual-machine:~/桌面/a$ ls
1  hello.c  hello.h  hello.o  libmyhello.a  main.c  main.o
//其中1为可执行文件

运行文件

shu@shu-virtual-machine:~/桌面/a$ ./1
Hello everyone!

删除静态库文件在执行文件

shu@shu-virtual-machine:~/桌面/a$ rm -rf libmyhello.a
shu@shu-virtual-machine:~/桌面/a$ ls
1  hello.c  hello.h  hello.o  main.c  main.o
shu@shu-virtual-machine:~/桌面/a$ ./1
Hello everyone!
//静态库使用就OK了。

下面进行动态库的使用
首先通过目标文件建立动态库文件前缀为lib,文件名,后缀为.so
gcc命令为gcc -shared -fPIC -o libmyhello.so hello.o

root@shu-virtual-machine:~/桌面/a# gcc -shared -fPIC -o libmyhello.so hello.o
root@shu-virtual-machine:~/桌面/a# ls
1  2  hello.c  hello.h  hello.o  libmyhello.a  libmyhello.so  main.c  main.o

接下来就是使用动态库,将libmyhello.so移动到/usr/lib

sudo cp  libmyhello.so /usr/lib

生成可执行文件,并执行

root@shu-virtual-machine:~/桌面/a# gcc main.c libmyhello.so -o 2
root@shu-virtual-machine:~/桌面/a# ls
1  2  hello.c  hello.h  hello.o  libmyhello.a  libmyhello.so  main.c  main.o
root@shu-virtual-machine:~/桌面/a# ./2
Hello everyone!
root@shu-virtual-

总结:在动态库和静态库同名时系统会优先使用动态库除非强调静态库,在选择动态库的时候,我们要将自己定义的动态库放入目录/usr/lib下面

gcc -o 2 main.c -L. lmyhello

静态库和动态库文件的使用

在目录d下面创建相关程序文本文件

shu@shu-virtual-machine:~/桌面$ cd d
shu@shu-virtual-machine:~/桌面/d$ touch 1.c 2.c 3.h 4.c
shu@shu-virtual-machine:~/桌面/d$ ls
1.c  2.c  3.h  4.c

//1.c
#include<stdio.h>
void print1(int arg)
{
printf("1 print arg:%d\n",arg);
}
//2.c
#include<stdio.h>
void print2(char *arg)
{
printf("2 print arg:%s\n",arg);
}
//3.h
#ifndef _3_H_
#define _3_H_
#include<stdio.h>
void print1(int);
void print2(char *);
#endif
//4.c
#include<stdio.h>
#include"3.h"
int main()
{
print1(1);
print2("test");
return 0;
}

生成目标文件后在生成静态库

shu@shu-virtual-machine:~/桌面/d$ gcc -c 1.c 2.c
shu@shu-virtual-machine:~/桌面/d$ ls
1.c  1.o  2.c  2.o  3.h  4.c
shu@shu-virtual-machine:~/桌面/d$ ar -crv liball.a 1.o 2.o
a - 1.o
a - 2.o
shu@shu-virtual-machine:~/桌面/d$ ls
1.c  1.o  2.c  2.o  3.h  4.c  liball.a

执行静态库文件和主程序

shu@shu-virtual-machine:~/桌面/d$ gcc -o all 4.c -L. -lall
shu@shu-virtual-machine:~/桌面/d$ ls
1.c  1.o  2.c  2.o  3.h  4.c  all  liball.a
shu@shu-virtual-machine:~/桌面/d$ ./all
1 print arg:1
2 print arg:test

生成动态库文件

shu@shu-virtual-machine:~/桌面/d$ gcc -c -fPIC 1.c 2.c
//生成fpic目标文件才能使后面编译动态库时不出错误
shu@shu-virtual-machine:~/桌面/d$ ls
1.c  1.o  2.c  2.o  3.h  4.c  all  liball.a
shu@shu-virtual-machine:~/桌面/d$ gcc -shared -fPIC -o liball.so 1.o 2.o
shu@shu-virtual-machine:~/桌面/d$ ls
1.c  1.o  2.c  2.o  3.h  4.c  all  liball.a  liball.so

连接动态库并执行主程序

shu@shu-virtual-machine:~/桌面/d$ gcc -o all1 4.c liball.so
shu@shu-virtual-machine:~/桌面/d$ ls
1.c  1.o  2.c  2.o  3.h  4.c  all  all1  liball.a  liball.so
//将liball.so移动到/sur/lib目录下,因为系统要先从目录/sur/lib/下面找动态库函数
shu@shu-virtual-machine:~/桌面/d$ sudo cp liball.so /usr/lib
[sudo] shu 的密码: 
shu@shu-virtual-machine:~/桌面/d$ ls
1.c  1.o  2.c  2.o  3.h  4.c  all  all1  liball.a  liball.so
shu@shu-virtual-machine:~/桌面/d$ ./all1
1 print arg:1
2 print arg:test
//运行结果如图

编写程序并生成动态库和静态库,运行程序

创建下列函数文本文件

//main.c
#include<stdio.h>
#include"1.h"
int main()
{
int x=4,y=2;
float t=x2x(x,y);
float s=x2y(x,y);
printf("%f\n",t);
printf("%f\n",s);
}
//x2x.c
#include<stdio.h>
float x2x(int x,int y)
{float n=(float)x/y;
return n;
}
//x2y.c
#include<stdio.h>
float x2y(int a,int b)
{
float z=a+b;
return z;
}
//1.h
#ifndef _1_H_
#define _1_H_
#include<stdio.h>
float x2x(int x,int y);
float x2y(int x,int y);
#endif

生成目标文件后生成静态库并执行文件

shu@shu-virtual-machine:~/桌面/c$ gcc -c x2x.c x2y.c
shu@shu-virtual-machine:~/桌面/c$ ls
1.h  main.c  x2x.c  x2x.o  x2y.c  x2y.o
shu@shu-virtual-machine:~/桌面/c$ ar -crv liball.a x2x.o x2y.o
a - x2x.o
a - x2y.o
shu@shu-virtual-machine:~/桌面/c$ ls
1.h  liball.a  main.c  x2x.c  x2x.o  x2y.c  x2y.o
shu@shu-virtual-machine:~/桌面/c$ gcc -o all main.c -L. -lall
shu@shu-virtual-machine:~/桌面/c$ ls
1.h  all  liball.a  main.c  x2x.c  x2x.o  x2y.c  x2y.o
shu@shu-virtual-machine:~/桌面/c$ ./all
2.000000
6.000000

生成动态库并执行

shu@shu-virtual-machine:~/桌面/c$ gcc -c -fPIC x2x.c x2y.c
shu@shu-virtual-machine:~/桌面/c$ gcc -shared -fPIC -o liball.so x2x.o x2y.o
shu@shu-virtual-machine:~/桌面/c$ ls
1.h  all  liball.a  liball.so  main.c  x2x.c  x2x.o  x2y.c  x2y.o
shu@shu-virtual-machine:~/桌面/c$ sudo cp liball.so /usr/lib
shu@shu-virtual-machine:~/桌面/c$ ls
1.h  all  liball.a  liball.so  main.c  x2x.c  x2x.o  x2y.c  x2y.o
shu@shu-virtual-machine:~/桌面/c$ gcc main.c liball.so -o all1
shu@shu-virtual-machine:~/桌面/c$ ls
1.h  all  all1  liball.a  liball.so  main.c  x2x.c  x2x.o  x2y.c  x2y.o
shu@shu-virtual-machine:~/桌面/c$ ./all1
2.000000
6.000000

linux gcc下常用命令

创建文本文件并理解编译过程

shu@shu-virtual-machine:~$ cd ~/桌面/e
shu@shu-virtual-machine:~/桌面/e$ touch main.c
shu@shu-virtual-machine:~/桌面/e$ gedit main.c
shu@shu-virtual-machine:~/桌面/e$ gcc -E main.c -o main.i
shu@shu-virtual-machine:~/桌面/e$ ls
main.c  main.i

对main.c进行预处理
接下来对main.c进行汇编

shu@shu-virtual-machine:~/桌面/e$ gcc -s main.i -o main.s
shu@shu-virtual-machine:~/桌面/e$ ls
main.c  main.i  main.s

之后可以对其进行汇编文件,生成目标文件

shu@shu-virtual-machine:~/桌面/e$ gcc -c main.c
shu@shu-virtual-machine:~/桌面/e$ ls
main.c  main.i  main.o  main.s
shu@shu-virtual-machine:~/桌面/e$

最后对目标文件进行封装连接

shu@shu-virtual-machine:~/桌面/e$ gcc main.o -o main
shu@shu-virtual-machine:~/桌面/e$ ls
main  main.c  main.i  main.o  main.s

编译目标文件,其实是在系统目录下找到include库函数

shu@shu-virtual-machine:~/桌面/e$ gcc -c -I /usr/dev/mysql/include main.c -o 1
shu@shu-virtual-machine:~/桌面/e$ ls
1  main  main.c  main.i  main.o  main.s
//1为目标文件

在目录下找到相关文件连接到可执行文件

shu@shu-virtual-machine:~/桌面/e$ gcc main.o -o 2
shu@shu-virtual-machine:~/桌面/e$ ./2
hello world

分析gcc编译后的相关文件

shu@shu-virtual-machine:~/桌面/e$ gcc main.c -o main
shu@shu-virtual-machine:~/桌面/e$ size main
   text	   data	    bss	    dec	    hex	filename
   1182	    552	      8	   1742	    6ce	main

动态库连接,用size来查看大小

hu@shu-virtual-machine:~/桌面/e$ ldd main
	linux-vdso.so.1 =>  (0x00007ffe1f276000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f30bb206000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f30bb5d0000)
//用来查看执行目标引用了哪些动态库文件

静态库连接

shu@shu-virtual-machine:~/桌面/e$ gcc -static main.c -o main1
shu@shu-virtual-machine:~/桌面/e$ size main1
   text	   data	    bss	    dec	    hex	filename
 824102	   7284	   6360	 837746	  cc872	main1
 //size可以用来查看大小,观察静态库连接过程
 shu@shu-virtual-machine:~/桌面/e$ ldd main1
	不是动态可执行文件
	//说明没有动态连接

分析生成的文件格式

shu@shu-virtual-machine:~/桌面/e$ readelf -S main
共有 31 个节头,从偏移量 0x19d8 开始:

节头:
  [] 名称              类型             地址              偏移量
       大小              全体大小          旗标   链接   信息   对齐
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000400238  00000238
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
       000000000000001c  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           00000000004002b8  000002b8
       0000000000000060  0000000000000018   A       6     1     8
  [ 6] .dynstr           STRTAB           0000000000400318  00000318
       000000000000003d  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           0000000000400356  00000356
       0000000000000008  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          0000000000400360  00000360
       0000000000000020  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             0000000000400380  00000380
       0000000000000018  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             0000000000400398  00000398
       0000000000000030  0000000000000018  AI       5    24     8
  [11] .init             PROGBITS         00000000004003c8  000003c8
       000000000000001a  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         00000000004003f0  000003f0
       0000000000000030  0000000000000010  AX       0     0     16
  [13] .plt.got          PROGBITS         0000000000400420  00000420
       0000000000000008  0000000000000000  AX       0     0     8
  [14] .text             PROGBITS         0000000000400430  00000430
       0000000000000182  0000000000000000  AX       0     0     16
  [15] .fini             PROGBITS         00000000004005b4  000005b4
       0000000000000009  0000000000000000  AX       0     0     4
  [16] .rodata           PROGBITS         00000000004005c0  000005c0
       0000000000000010  0000000000000000   A       0     0     4
  [17] .eh_frame_hdr     PROGBITS         00000000004005d0  000005d0
       0000000000000034  0000000000000000   A       0     0     4
  [18] .eh_frame         PROGBITS         0000000000400608  00000608
       00000000000000f4  0000000000000000   A       0     0     8
  [19] .init_array       INIT_ARRAY       0000000000600e10  00000e10
       0000000000000008  0000000000000000  WA       0     0     8
  [20] .fini_array       FINI_ARRAY       0000000000600e18  00000e18
       0000000000000008  00000000

反汇编ELF,使用相关指令将其反汇编

shu@shu-virtual-machine:~/桌面/e$ objdump -D main

main:     文件格式 elf64-x86-64


Disassembly of section .interp:

0000000000400238 <.interp>:
  400238:	2f                   	(bad)  
  400239:	6c                   	insb   (%dx),%es:(%rdi)
  40023a:	69 62 36 34 2f 6c 64 	imul   $0x646c2f34,0x36(%rdx),%esp
  400241:	2d 6c 69 6e 75       	sub    $0x756e696c,%eax
  400246:	78 2d                	js     400275 <_init-0x153>
  400248:	78 38                	js     400282 <_init-0x146>
  40024a:	36 2d 36 34 2e 73    	ss sub $0x732e3436,%eax
  400250:	6f                   	outsl  %ds:(%rsi),(%dx)
  400251:	2e 32 00             	xor    %cs:(%rax),%al

Disassembly of section .note.ABI-tag:

0000000000400254 <.note.ABI-tag>:
  400254:	04 00                	add    $0x0,%al
  400256:	00 00                	add    %al,(%rax)
  400258:	10 00                	adc    %al,(%rax)
  40025a:	00 00                	add    %al,(%rax)
  40025c:	01 00                	add    %eax,(%rax)
  40025e:	00 00                	add    %al,(%rax)
  400260:	47                   	rex.RXB
  400261:	4e 55                	rex.WRX push %rbp
  400263:	00 00                	add    %al,(%rax)
  400265:	00 00                	add    %al,(%rax)
  400267:	00 02                	add    %al,(%rdx)
  400269:	00 00                	add    %al,(%rax)
  40026b:	00 06                	add    %al,(%rsi)
  40026d:	00 00                	add    %al,(%rax)
  40026f:	00 20                	add    %ah,(%rax)
  400271:	00 00                	add    %al,(%rax)
	...


opencv下的 图像处理技术

安装opencv之后进行下列操作
opencv安装博客上有很多教程
创建目录创建文本文件代码如下
在编译代码时要在同一个目录下要保存一张图片为lena.jpg格式

shu@shu-virtual-machine:~/桌面$ mkdir e
shu@shu-virtual-machine:~/桌面$ cd e
shu@shu-virtual-machine:~/桌面/e$ touch code
shu@shu-virtual-machine:~/桌面/e$ gedit code.cpp
shu@shu-virtual-machine:~/桌面/e$ g++ code.cpp -o test1 `pkg-config --cflags --libs opencv`
shu@shu-virtual-machine:~/桌面/e$ ls
code  code.cpp  test1
shu@shu-virtual-machine:~/桌面/e$ ./test1
shu@shu-virtual-machine:~/桌面/e$ ls
code  code.cpp  lena.jpg  test1  test.png

//code.cpp
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
	CvPoint center;
    double scale = -3; 

	IplImage* image = cvLoadImage("lena.jpg");
	argc == 2? cvLoadImage(argv[1]) : 0;
	
	cvShowImage("Image", image);
	
	
	if (!image) return -1; 	center = cvPoint(image->width / 2, image->height / 2);
	for (int i = 0;i<image->height;i++)
		for (int j = 0;j<image->width;j++) {
			double dx = (double)(j - center.x) / center.x;
			double dy = (double)(i - center.y) / center.y;
			double weight = exp((dx*dx + dy*dy)*scale);
			uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3);
			ptr[0] = cvRound(ptr[0] * weight);
			ptr[1] = cvRound(ptr[1] * weight);
			ptr[2] = cvRound(ptr[2] * weight);
		}

	Mat src;Mat dst;
	src = cvarrToMat(image);
	cv::imwrite("test.png", src);

    cvNamedWindow("test",1);  	imshow("test", src);
	 cvWaitKey();
	 return 0;
}

运行结果
原图
原图
运行图
在这里插入图片描述
opencv下面,进行视频播放
先进行代码编译和创建
test.cpp

#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
	//从摄像头读取视频
	VideoCapture capture("man.mp4");
	//循环显示每一帧
	while(1){
		Mat frame;//定义一个Mat变量,用于存储每一帧的图像
		capture >> frame;//读取当前帧
		if(frame.empty())//播放完毕,退出
			break;
		imshow("读取视频帧",frame);//显示当前帧
		waitKey(30);//掩饰30ms
	}
	system("pause");
	return 0;
}

在这个目录下要保存一 man.mp4视频

shu@shu-virtual-machine:~/桌面/e$ touch test2.cpp
shu@shu-virtual-machine:~/桌面/e$ gedit test2.cpp
shu@shu-virtual-machine:~/桌面/e$ g++ test2.cpp -o test2 `pkg-config --cflags --libs opencv`
shu@shu-virtual-machine:~/桌面/e$ 
shu@shu-virtual-machine:~/桌面/e$ ls
code  code.cpp  lena.jpg  man.mp4  test1  test2  test2.cpp  test.png
shu@shu-virtual-machine:~/桌面/e$ ./test2
sh: 1: pause: not found

运行结果
在这里插入图片描述
opencv下进行录制视频
创建test3.cpp,完成相关编程

/*********************************************************************
打开电脑摄像头,空格控制视频录制,ESC退出并保存视频RecordVideo.avi
*********************************************************************/
#include<iostream>
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;

int main()
{
	//打开电脑摄像头
	VideoCapture cap(0);
	if (!cap.isOpened())
	{
		cout << "error" << endl;
		waitKey(0);
		return 0;
	}

	//获得cap的分辨率
	int w = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_WIDTH));
	int h = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
	Size videoSize(w, h);
	VideoWriter writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, videoSize);
	
	Mat frame;
	int key;//记录键盘按键
	char startOrStop = 1;//0  开始录制视频; 1 结束录制视频
	char flag = 0;//正在录制标志 0-不在录制; 1-正在录制

	while (1)
	{
		cap >> frame;
		key = waitKey(100);
		if (key == 32)//按下空格开始录制、暂停录制   可以来回切换
		{
			startOrStop = 1 - startOrStop;
			if (startOrStop == 0)
			{
				flag = 1;
			}
		}
		if (key == 27)//按下ESC退出整个程序,保存视频文件到磁盘
		{
			break;
		}

		if (startOrStop == 0 && flag==1)
		{
			writer << frame;
			cout << "recording" << endl;
		}
		else if (startOrStop == 1)
		{
			flag = 0;
			cout << "end recording" << endl;
			
		}
		imshow("picture", frame);
	}
	cap.release();
	writer.release();
	destroyAllWindows();
	return 0;
}
shu@shu-virtual-machine:~/桌面/e$ g++ test3.cpp -o test3 `pkg-config --cflags --libs opencv`
shu@shu-virtual-machine:~/桌面/e$ ls
code  code.cpp  lena.jpg  man.mp4  test1  test2  test2.cpp  test3  test3.cpp  test.png
shu@shu-virtual-machine:~/桌面/e$ ./test3
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
end recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
recording
shu@shu-virtual-machine:~/桌面/e$ ls
code  code.cpp  lena.jpg  man.mp4  RecordVideo.avi  test1  test2  test2.cpp  test3  test3.cpp  test.png

录制成功后生成.avi文件
在这里插入图片描述

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:16:59  更:2021-10-09 16:18:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 10:17:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码