《Linux C函数与算法》
《Linux C函数与算法》 |
| 版本 | 作者 | 参与者 | 完成日期 | 备注 |
| YanlzLinux_C_V01_1.0 | 严立钻 |
| 2020.02.03 |
|
|
|
|
|
|
|
##《Linux C函数与算法》发布说明:
++++“Linux C函数与算法”:是对“Linux系统编程”的综合探索;开发Linux环境下的应用程序时,需要使用大量的Linux函数;这些函数有的属于Linux操作系统的API,有的属于C语言的标准库函数;
++++“Linux C函数与算法”:定位在一个科普类知识,了解Linux环境下的应用程序开发!
++++Tips:“Linux C独立篇”:是《C/C++函数与算法》的姊妹篇,“Linux C独立篇”将以Linux系统为开发环境;

++++姊妹篇推荐:
++++【C/C++函数与算法(C库独立篇)】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104026090
++++【C/C++函数与算法(C++库独立篇)】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104062275
++++【C/C++函数与算法(算法独立篇)】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104062527
++++【Linux系统编程】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9694767.html
++++【C++C铸就生存利器】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9325802.html
++++【人工智能AI2026】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9212024.html
++++【立钻哥哥优快云空间】:https://blog.youkuaiyun.com/VRunSoftYanlz/
@@提示:有些博客可能只是开了头,如果感兴趣的同学,可以“点赞”或“评论区留言”,只要关注的同学多了,那就会继续完善哟!(“++==”,表示没有写完的,如果关注度不高就不完善了;“++ok++”,表示此篇博客已经完成,是阶段性完整的!)

++++VR云游戏=Unity+SteamVR+云技术+5G+AI;(说明:AI人工智能不是我们的主要研究技术,只是了解一下,领略一下有风的感觉!但是,VR是我们的研究重点)

##《Linux C函数与算法》目录
#第一篇:Linux系统编程
#第二篇:Linux系统下的C开发
#第三篇:Linux网络编程
#第四篇:Linux内核驱动
#第五篇:立钻哥哥带您Linux系统编程
#第一篇:Linux系统编程
#第一篇:Linux系统编程 |
#第一篇:Linux系统编程
++++立钻哥哥:程序是一个精确说明如何进行计算的指令序列;编写程序可以说就是这样一个过程:把复杂的任务分解成子任务,把子任务再分解成更简单的任务,层层分解,直到最后简单到可以用指令来完成;
++++A1、文件与I/O
++++A2、文件系统
++++A3、进程
++++A4、Shell脚本
++++A5、正则表达式
++++A6、信号
++++A7、终端、作业控制与守护进程
++++A8、线程
++++A9、TCP/IP协议基础
++++A10、Socket编程
++++A11、立钻哥哥带您Linux系统编程
++A1、文件与I/O
++A1、文件与I/O |
++A1、文件与I/O
++++立钻哥哥:学习Linux系统函数,这些函数的用法必须结合Linux内核的工作原理来理解,因为系统函数正是内核提供给应用程序的接口,而要理解内核的工作原理,必须熟练掌握C语言,因为内核也是用C语言写的,在描述内核工作原理时必然要用到“指针”、“结构体”、“链表”等来组织;
++++[文件描述符]:是文件描述符表的索引(0、1、2、3),用int型变量来保存;当调用open打开一个现有文件或创建一个新文件时,内核分配一个新的文件描述符并返回给进程,当读写该文件时,文件描述符被作为参数传给read或write;
#define STDIN_FILENO 0#define STDOUT_FILENO 1#define STDERR_FILENO 2 |


++open
++++立钻哥哥:open函数可以打开或创建一个文件;
int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode); |
++close
++++立钻哥哥:close函数关闭一个已打开文件;
int close(int fd); |
++read/write
++++立钻哥哥:read函数从打开的设备或文件中读取数据;write函数向打开的设备或文件中写数据;
ssize_t read(int fd, void *buf, size_t count);ssize_t write(int fd, const void *buf, size_t count);
|
| #include <unistd.h> #include <stdlib.h>
int main(void){ char buf[10]; int n;
n = read(STDIN_FILENO, buf, 10); if(n < 0){ perror(“立钻哥哥:read STDIN_FILENO”); exit(1); } write(STDOUT_FILENO, buf, n);
return 0; } |
++lseek
++++立钻哥哥:lseek和标准IO库的fseek函数类似,可以移动当前读写位置(或者叫偏移量);
off_t lseek(int fd, off_t offset, int whence);
|
| off_t currpos; currpos = lseek(fd, 0, SEEK_CUR); |
++fcntl
++++立钻哥哥:可以用fcntl函数改变一个已打开的文件的属性,可以重新设置读、写、追加、非阻塞等标志(这些标志称为File Status Flag),而不必重新open文件;
int fcntl(int fd, int cmd);int fcntl(int fd, int cmd, long arg);int fcntl(int fd, int cmd, struct flock *lock); |
++ioctl
++++立钻哥哥:ioctl用于向设备发控制和配置命令,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据;
int ioctl(int d, int request, ...); |
++mmap
++++立钻哥哥:mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来做而不需要read/write函数;
void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off);int munmap(void *addr, size_t len); |

++A2、文件系统
++A2、文件系统 |
++A2、文件系统
++++立钻哥哥:文件系统在内核中是如何实现的?如何呈现给用户一个树状的目录结构?如何处理用户的文件和目录操作请求?磁盘是一种顺序的存储介质,一个树状的目录结构如何扯成一条线存到磁盘上?怎样设计文件系统的存储格式使访问磁盘的效率最高?各种文件和目录操作在磁盘上实际效果是什么?
++++Linux支持各种各样的文件系统格式:ext2、ext3、reiserfs、FAT、NTFS、iso9660等,不同的磁盘分区、光盘或其它存储设备都有不同的文件系统格式,然后这些文件系统都可以mount到某个目录下;


++ext2文件系统
++++立钻哥哥:一个磁盘可以划分成多个分区,每个分区必须先格式化工具格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写一些管理存储布局的信息;文件系统中存储的最小单位是块(Block),一个块究竟多大是在格式化时确定的;启动块是由PC标准规定的,用来存储磁盘分区信息和启动信息,任何文件系统都不能使用启动块;启动块之后才是ext2文件系统的开始,ext2文件系统将整个分区划成若干个同样大小的块组(Block Group),每个块组都由:超级块(Super Block)、块组描述符表(GDT,Group Descriptor Table)、块位图(Block Bitmap)、inode位图(inode Bitmap)、inode表(inode Table)、数据块等部分组成;
++++[超级块(Super Block)]:描述整个分区的文件系统信息,例如块大小、文件系统版本号、上次mount的时间等等;超级块在每个块组的开头都有一份拷贝;
++++[块组描述符表(GDT,Group Descriptor Table)]:由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符;
++++[块位图(Block Bitmap)]:是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit代表本块组中的一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用;
++++[inode位图(inode Bitmap)]:和块位图类似,本身占一个块,其中每个bit表示一个inode是否空闲可用;
++++[inode表(inode Table)]:inode表占多少个块在格式化时就要决定并写入块组描述符中;
++++[数据块]:对于常规文件,文件的数据存储在数据块中;

++VFS(Virtual Filesystem,虚拟文件系统)
++++立钻哥哥:Linux内核在各种不同的文件系统格式之上做了一个抽象层,使得文件、目录、读写访问等概念成为抽象层的概念,因此各种文件系统看起来用起来都一样,这个抽象层称为虚拟文件系统(VFS,Virtual Filesystem);
++++每个进程在PCB(Process Control Block)中都保存着一份文件描述符表,文件描述符就是这个表的索引,每个表项都有一个指向已打开文件的指针:已打开的文件在内核中用file结构体表示,文件描述符表中的指针指向file结构体;

++A3、进程
++A3、进程 |
++A3、进程
++++立钻哥哥:每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体;
++++[fork和exec]:是两个重要的系统调用;fork的作用是根据一个现有的进程复制出一个新进程,原来的进程称为父进程(Parent Process),新进程称为子进程(Child Process);系统中同时运行着很多进程,这些进程都是从最初只有一个进程开始一个一个复制出来的;



++exit和_exit函数
++++立钻哥哥:exit和_exit函数用于终止一个进程;
void exit(int status);void _exit(int status); |
++fork
++++立钻哥哥:fork用来创建新进程;
pid_t fork(void); |
++exec函数族
++++立钻哥哥:用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序;当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行;调用exec并不创建新进程,所以调用exec前后该进程的id并未改变;
int execl(const char *path, const char *arg, ...);int execlp(const char *file, const char *arg, ...);int execle(const char *path, const char *arg, ..., char *const envp[]);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execve(const char *path, char *const argv[], char *const envp[]); |

++wait和waitpid
++++立钻哥哥:一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中保存了一些信息:如果是正常终止则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号是哪个;这个进程的父进程可以调用wait或waitpid获取这些信息,然后彻底清除掉这个进程;
++++如果一个进程已经终止,但是它的父进程尚未调用wait或waitpid对它进行清理,这时的进程状态称为僵尸(Zombie)进程;任何进程在刚终止时都是僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了;
pid_t wait(int *status);pid_t waitpid(pit_t pid, int *status, int options); |
++进程间通信
++++立钻哥哥:每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷贝到内核缓冲区,进程2再从内核缓冲区把数据独奏,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication);
++++[管道]:管道是一种最基本的IPC机制,由pipe函数创建;
int pipe(int filedes[2]); |

++A4、Shell脚本
++A5、正则表达式
++A6、信号
++A7、终端、作业控制与守护进程
++A8、线程
++A9、TCP/IP协议基础
++A10、Socket编程
++A11、立钻哥哥带您Linux系统编程
++A4、Shell脚本++A5、正则表达式++A6、信号++A7、终端、作业控制与守护进程++A8、线程++A9、TCP/IP协议基础++A10、Socket编程++A11、立钻哥哥带您Linux系统编程 |
&&Tips:“Linux系统编程”独立成篇:
++++Linux系统编程:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104151861

#第二篇:Linux系统下的C开发
#第二篇:Linux系统下的C开发 |
#第二篇:Linux系统下的C开发
++++立钻哥哥:开发Linux环境下的应用程序时,需要使用大量的Linux函数;这些函数有的属于Linux操作系统的API,有的属于C语言的标准库函数;
++++B1、初级I/O函数
++++B2、文件管理操作函数
++++B3、标准I/O函数
++++B4、格式化输入输出函数
++++B5、进程控制
++++B6、进程间通信函数
++++B7、信号函数
++++B8、用户、组函数及环境变量函数
++++B9、错误处理与内存分配函数
++++B10、日志函数、动态函数与正则表达式函数
++++B11、时间函数
++++B12、socket相关函数
++++B13、字符测试函数
++++B14、数据转换函数
++++B15、字符串处理函数
++++B16、数学计算函数
++++B17、随机数及数据加密函数
++++B18、数据结构函数
++++B19、立钻哥哥整理的其他函数
++++B20、立钻哥哥带您Linux系统编程实战
++B1、初级I/O函数
++B1、初级I/O函数 |
++B1、初级I/O函数
++++立钻哥哥:计算机由两个重要的概念:时间和空间;计算机将时间这个概念抽象为进程,而将空间这个概念抽象为文件;这些函数实现了Linux环境下的基本文件I/O文件;
++++B1.1、close
++++B1.2、creat
++++B1.3、dup
++++B1.4、dup2
++++B1.5、fcntl
++++B1.6、fsync
++++B1.7、lseek
++++B1.8、open
++++B1.9、read
++++B1.10、sync
++++B1.11、write
++++B1.1、close
++++B1.1、close |
++B1.1、close
++++立钻哥哥:close函数用来关闭一个已经打开的文件,并且将文件修改过的内容回写到磁盘;当close函数关闭文件后,该文件占用的文件描述符则再次可用;
int close(int fd); |
++++close的参数必须是一个文件描述符,不能是一个随意的整数;由于文件描述符在内核的进程控制结构中实现为一个文件描述符数组,因此close的参数过大会造成该数组的越界,从而引起系统崩溃;
++++B1.2、creat
++++B1.2、creat |
++B1.2、creat
++++立钻哥哥:creat函数创建一个新文件,并以“只写”的方式将这个新创建的文件打开,返回新文件的文件描述符;
int creat(const char *pathname, mode_t mode); |
++++B1.3、dup
++++B1.3、dup |
++B1.3、dup
++++立钻哥哥:dup函数总是找到进程文件表中第一个可用的文件描述符,将参数指定的文件复制到该描述符后,返回这个描述符;
int dup(int fields); |
++++dup函数总是将复制的文件复制到进程中第一个可用的文件描述符的位置,因此利用这一个特性可以知道进程中最小可用的文件描述符;
++++B1.4、dup2
++++B1.4、dup2 |
++B1.4、dup2
++++立钻哥哥:dup2函数和dup函数类似,不过dup函数允许使用第二个参数指定将文件描述符复制到哪一个文件描述符上;
int dup2(int filedes, int fileds2); |
++++dup2函数会将指定的目的描述符所代表的文件关闭,之后再进行复制;
++++B1.5、fcntl
++++B1.5、fcntl |
++B1.5、fcntl
++++立钻哥哥:fcntl函数用来通过文件描述符修改文件的状态属性,具体的修改功能由fcntl函数的命令(第二个参数)来决定;
int fcntl(int filedes, int cmd, ...); |
++++fcntl函数相当于一个文件操作的大集合;函数均可用fcntl函数代替;例如dup函数等;
++++B1.6、fsync
++++B1.6、fsync |
++B1.6、fsync
++++立钻哥哥:fsync函数可以确保文件的实际写出,该函数会阻塞直到修改的盘块写到外存后才返回;
int fsync(int filedes); |
++++fsync函数会将内存中缓冲区中的数据内容回写到磁盘空间,但是是否会达到实际的回写效率需要依赖于文件系统的实现;
++++B1.7、lseek
++++B1.7、lseek |
++B1.7、lseek
++++立钻哥哥:lseek函数可以更改打开文件的偏移量,实现在文件内部的定位;
off_t lseek(int filedes, off_t offset, int whence); |
++++如果lseek函数的第3个参数超过文件本身的长度,会造成一个磁盘文件的空洞;这时该空洞并不占用磁盘空间;
++++使用“lseek(fd, 0, SEEK_CUR);”,这种方式调用lseek函数可以得到文件当前的偏移位置;
++++B1.8、open
++++B1.8、open |
++B1.8、open
++++立钻哥哥:open用于打开一个文件;
int open(const char *pathname, int oflag, ...); |
++++open函数的第一个参数指定要打开的文件,有两种方式指定该文件;使用该文件的绝对路径名(或者相对路径名),操作系统将根据路径名寻找文件;或者使用该文件的文件名,操作系统只在当前工作目录寻找该文件;
++++open函数可以用来创建一个新文件,因此可以替代creat函数;
++++调用open函数创建一个新文件的时候,该文件的访问权限受到文件权限屏蔽掩码“umask”的影响;
++++B1.9、read
++++B1.9、read |
++B1.9、read
++++立钻哥哥:read函数读取一个已经打开的文件的内容;
ssize_t read(int filedes, void *buf, size_t nbytes); |
++++read函数不会在读入的内容后面添加“\0”结束符,这一点和C语言函数库中提供的读文件函数是不同的,如果需要的话必须手动添加;
++++B1.10、sync
++++B1.10、sync |
++B1.10、sync
++++立钻哥哥:sync函数将所有打开的文件回写到磁盘上;
void sync(void); |
++++sync函数将文件中修改过内容的盘块放入系统队列后就返回,并不等待盘块实际写入外存;因此该函数能够加快文件同步速度,但是并不能保证真正的文件同步;
++++B1.11、write
++++B1.11、write |
++B1.11、write
++++立钻哥哥:write函数输出内容到一个已经打开的文件中;
ssize_t write(int filedes, void *buf, size_t nbytes); |
++++对于write函数来讲,常见的出错原因是外存没有足够的存储空间或者文件长度超过了进程文件长度的限制;
++B2、文件管理操作函数
++B2、文件管理操作函数 |
++B2、文件管理操作函数
++++立钻哥哥:在Linux环境下,每一个文件都保存在内核中的stat结构中,该结构保存一个文件的状态;这些stat结构几乎包括了一个用户感兴趣的文件所有信息;
++++B2.1、access
++++B2.2、alphasort
++++B2.3、chdir
++++B2.4、chmod
++++B2.5、chown
++++B2.6、chroot
++++B2.7、closedir
++++B2.8、fchdir
++++B2.9、fchmod
++++B2.10、fstat
++++B2.11、ftruncate
++++B2.12、ftw
++++B2.13、get_current_dir_name
++++B2.14、getcwd
++++B2.15、lchown
++++B2.16、link
++++B2.17、lstat
++++B2.18、nftw
++++B2.19、opendir
++++B2.20、readdir
++++B2.21、readlink
++++B2.22、realpath
++++B2.23、remove
++++B2.24、rename
++++B2.25、rewinddir
++++B2.26、seekdir
++++B2.27、stat
++++B2.28、symlink
++++B2.29、telldir
++++B2.30、truncate
++++B2.31、umask
++++B2.32、unlink
++++B2.1、access
++++B2.1、access |
++B2.1、access
++++立钻哥哥:access函数进行访问权限测试,测试调用者进程是否有访问文件的权限;
int access(const char *pathname, int mode); |
++++access函数使用进程的实际用户ID和实际组ID与文件的所有者ID和ID进行比较;
++++如果进程的实际用户ID和文件的所有者ID相等,则使用参数mode指定的权限与文件的所有者权限进行比较;
++++B2.2、alphasort
++++B2.2、alphasort |
++B2.2、alphasort
++++立钻哥哥:alphasort函数按字典序比较两个目录项的文件名,并且返回比较结果;
int alphasort(const struct dirent a, const struct dirent b); |
++++alphasort函数的排序方式与strcmp函数相同;
++++B2.3、chdir
++++B2.3、chdir |
++B2.3、chdir
++++立钻哥哥:chdir函数改变进程的工作目录;
int chdir(char *pathname); |
++++当进程的工作目录改变后,所有新创建的文件均在该目录下,所有程序中引用的相对路径名也全部以该目录为基准开始引用;
++++子进程的工作目录的改变不影响到父进程,父进程的工作目录的改变会影响到子进程;
++++B2.4、chmod
++++B2.4、chmod |
++B2.4、chmod
++++立钻哥哥:chmod函数改变文件的权限,将第二个参数表示的文件权限的标志位设置到文件的状态结构中;
int chmod(const char *pathname, mode_t mode); |
++++并不是所有的进程都可以随便改变文件的权限的,只有文件的所有者和根用户可以改变文件的权限;这一点体现了系统的安全性;
++++B2.5、chown
++++B2.5、chown |
++B2.5、chown
++++立钻哥哥:chown函数改变一个文件的所有者的用户ID;
int chown(const char *pathname, uid_t owner, gid_t group); |
++++更改文件的所有者是一项需要谨慎处理的操作,因为可能会导致安全问题;因此并不是所有的用户都可以修改文件的所有者ID的;如果需要修改一个文件的所有者ID和组ID,该用户必须是根用户;
++++B2.6、chroot
++++B2.6、chroot |
++B2.6、chroot
++++立钻哥哥:chroot函数改变进程的根目录;
int chroot(const char *pathname); |
++++chroot函数的参数表示新的进程根目录;子进程的根目录的改变不影响到父进程;相反父进程的根目录的改变会影响到子进程;
++++B2.7、closedir
++++B2.7、closedir |
++B2.7、closedir
++++立钻哥哥:closedir函数关闭一个目录文件,关闭之后则不能再应用该目录;
int closedir(DIR *dp); |
++++目录文件作为一种文件,再打开后必须关闭,否则会由于文件的进程打开文件过多而不能打开新的文件;因此opendir函数和closedir函数是配对出现的;
++++B2.8、fchdir
++++B2.8、fchdir |
++B2.8、fchdir
++++立钻哥哥:fchdir函数改变进程的工作目录,目的目录使用一个文件描述符表示;
int fchdir(int fd); |
++++当进程的工作目录改变后,所有新创建的文件均在该目录下,所有程序中引用的相对路径名也全部以该目录为基准开始引用;
++++B2.9、fchmod
++++B2.9、fchmod |
++B2.9、fchmod
++++立钻哥哥:fchmod函数改变文件的权限,将第二个参数表示的文件权限的标志位设置到文件的状态结构中;
int fchmod(int filedes, mode_t mode); |
++++并不是所有的进程都可以随便改变文件的权限的,只有文件的所有者和根用户可以改变文件的权限,这一点体现了系统的安全性;fchmod和chmod遵守同样的规律;
++++B2.10、fstat
++++B2.10、fstat |
++B2.10、fstat
++++立钻哥哥:fstat函数可以从一个打开文件的文件描述符上得到相关信息,stat结构用于存储文件的状态信息;
int fstat(int filedes, struct stat *restrict buf);
|
| //立钻哥哥:fstat函数从内核中取得文件的状态并且将其存储在参数buf所表示的stat结构中返回给用户;stat结构用于存储文件的状态信息; //stat结构,声明于sys/stat.h文件之中 struct stat{ mode_t st_mode; //文件类型和文件权限,两个成员作为一个位向量存储 ino_t st_ino; //i节点号 dev_t st_dev; //文件系统设备号 dev_t st_rdev; //硬件设备设备号 nlink_t st_nlink; //硬链接数 uid_t st_uid; //所有者用户ID gid_t st_gid; //所有者组ID off_t st_size; //文件的大小(字节数,只对于普通文件有效) time_t st_atime; //最近一次的访问时间 time_t st_mtime; //最近一次修改文件内容的时间 time_t st_ctime; //最近一次修改文件属性的时间 blksize_t st_blksie; //最合适的缓冲区大小 blkcnt_t st_blocks; //文件在外存上占用的盘块数 }; |
++++Linux环境下的文件都有自己的状态信息,例如文件的大小和文件的修改日期等,这些状态信息和文件的内容是分开存储的;
++++B2.11、ftruncate
++++B2.11、ftruncate |
++B2.11、ftruncate
++++立钻哥哥:ftruncate函数改变一个已经打开的文件的大小,如果新的大小小于文件的原大小,则放弃超出的部分;
int ftruncate(const char *pathname, off_t length); |
++++ftruncate函数的第二个参数表示将文件截短的字节数,超过这个字节数的部分将被系统放弃;如果文件的实际大小小于这个指定的值,则系统会自动拓展该文件;这时文件实际末尾和拓展的新末尾之间形成一个文件空洞;
++++B2.12、ftw
++++B2.12、ftw |
++B2.12、ftw
++++立钻哥哥:ftw函数从参数dir指定的目录开始,一层层地递归遍历子目录;每进入一个目录,便会调用参数*fn定义的函数来处理;
int ftw(const char *dir, int (*fn)(const char *file, const struct stat *sb, int flag), int depth); |
++++ftw函数用来遍历一个树形目录,对每一个子目录下的文件使用回调函数进行操作;
++++B2.13、get_current_dir_name
++++B2.13、get_current_dir_name |
++B2.13、get_current_dir_name
++++立钻哥哥:get_current_dir_name函数得到进程的当前工作目录,并且将这个目录的字符串形式存储在系统分配的空间中;
char *get_current_dir_name(); |
++++get_current_dir_name函数分配一块内存保存当前路径的字符串形式,系统会自动添加一个’\0’结束标志;
++++B2.14、getcwd
++++B2.14、getcwd |
++B2.14、getcwd
++++立钻哥哥:getcwd函数得到进程的当前工作目录,并且将这个目录的字符串形式存储在用户提供的缓冲区中;
char *getcwd(char *buf, size_t size); |
++++getcwd函数的第二个参数是存储当前目录字符串形式的缓冲区,该缓冲区可以容纳路径名的字符数加上一个’\0’结束符的长度;
++++B2.15、lchown
++++B2.15、lchown |
++B2.15、lchown
++++立钻哥哥:lchown函数改变符号链接文件本身的所有者;
int lchown(const char *pathname, uid_t owner, gid_t group); |
++++B2.16、link
++++B2.16、link |
++B2.16、link
++++立钻哥哥:link函数创建一个新的目录项,这个目录项使用参数newpath所表示的路径的最末端作为文件的文件名;
int link(const char *exitingpath, const char *newpath); |
++++Linux文件系统并不允许普通用户创建一个链接到目录的硬链接;因为这样会导致文件系统的目录属性结构中出现回路;根用户可以创建链接到目录的硬链接,但是这种操作应该杜绝;
++++一个文件可以对应多个目录项,也就是说多个不同名的文件可以具有相同的文件内容,因为它们都对应同一个磁盘文件;当一个磁盘文件没有目录项相对应时,这个文件将不能被系统所引用;因此当该文件不再处于打开状态时,系统也将删除该文件;
++++B2.17、lstat
++++B2.17、lstat |
++B2.17、lstat
++++立钻哥哥:lstat函数不跟踪符号链接,因此可以取得符号链接文件本身的文件状态信息;
int lstat(const char *restrict pathname, struct stat *restrict buf); |
++++Linux环境下的每一个文件都有自己的状态信息,状态信息和文件的内容是分开存储的,符号链接也是一样;
++++B2.18、nftw
++++B2.18、nftw |
++B2.18、nftw
++++立钻哥哥:nftw函数从参数dir指定的目录开始,一层层地递归遍历子目录;每进入一个目录,便会调用参数*fn定义的函数来处理;
int nftw(const char *dir, int (*fn)(const char *file, const struct stat *sb, int flag, struct FTW *s), int depth, int flags); |
++++nftw函数用来遍历一个树形目录,对每一个子目录下的文件使用回调函数进行操作;
++++B2.19、opendir
++++B2.19、opendir |
++B2.19、opendir
++++立钻哥哥:opendir函数打开一个目录文件,之后可以像操作普通文件一样操作该文件;
DIR *opendir(const char *pathname); |
++++目录文件作为一种文件,在打开后必须关闭,否则会造成文件的进程打开文件过多而不能打开新的文件,因此opendir和closedir是配对出现的;
++++B2.20、readdir
++++B2.20、readdir |
++B2.20、readdir
++++立钻哥哥:readdir函数读取目录中每一个文件的目录项,并将其返回;子目录作为文件的一种,同样会返回目录项;
struct direct *readdir(DIR *dp); |
++++readdir函数返回读取的文件的目录项,如果目录到达结尾或者出错readdir函数返回NULL;因此判断readdir函数是否出错应当判断errno变量的值;
++++B2.21、readlink
++++B2.21、readlink |
++B2.21、readlink
++++立钻哥哥:readlink函数读取符号链接的链接名,并且存入buf缓冲区中;
int readlink(const char *restrict pathname, char *restrict buf, size_t bufsize); |
++++readlink函数读取符号链接的链接名,并且存入buf缓冲区中;readlink函数不读取符号链接所指向的文件的内容,这一点要特别注意;buf缓冲区中的字符串不以’\0’结尾,如果需要,用户应当自行添加;
++++B2.22、realpath
++++B2.22、realpath |
++B2.22、realpath
++++立钻哥哥:realpath函数将一个相对路径转换为绝对路径后返回;
char *realpath(const char *path); |
++++realpath函数转换相对路径,将结果保存在一块分配的存储区中,在使用之后应当将其释放;
++++B2.23、remove
++++B2.23、remove |
++B2.23、remove
++++立钻哥哥:remove函数的参数pathname表示要删除的文件或目录;
int remove(const char *pathname); |
++++目录文件作为一种文件,其内部存储文件的目录项;每次读目录文件实际上跳过一个目录项的大小;
++++B2.24、rename
++++B2.24、rename |
++B2.24、rename
++++立钻哥哥:rename函数将原始路径表示的文件移动到新的路径上,因此可以实现文件的改名或者文件的移动;
int rename(const char *oldpath, const char *newpath); |
++++rename函数会将参数oldpath所指定的文件名称改为参数newpath所指的文件名称;若newpath所指定的文件已存在,则会被删除;
++++B2.25、rewinddir
++++B2.25、rewinddir |
++B2.25、rewinddir
++++立钻哥哥:rewinddir函数将一个目录的当前读写位置回到目录文件的开始处,这个操作称为回卷;
void rewinddir(DIR *dir); |
++++目录文件作为一种文件,其内部存储文件的目录项;每次读目录文件实际上跳过一个目录项的大小;因此目录文件也可以回卷;
++++B2.26、seekdir
++++B2.26、seekdir |
++B2.26、seekdir
++++立钻哥哥:seekdir函数在目录文件中定位,可以将目录文件当作普通文件一样指定文件内的读写位置;
void seekdir(DIR *dir, off_t offset); |
++++目录文件作为一种文件,其内部存储文件的目录项;每次读目录文件实际上跳过一个目录项的大小;因此目录文件也可以进行定位,人工地设定目录文件的读写位置;
++++B2.27、stat
++++B2.27、stat |
++B2.27、stat
++++立钻哥哥:stat函数得到文件的相关状态信息,stat结构用于存储文件的状态信息;
int stat(const char *restrict pathname, struct stat *restrict buf); |
++++Linux环境下文件的状态信息和文件的内容是分开存储的;
++++B2.28、symlink
++++B2.28、symlink |
++B2.28、symlink
++++立钻哥哥:symlink函数创建一个新的目录项sympath,并且使该目录项指向actualpath所表示的文件的目录项;
int symlink(const char *actualpath, const char *sympath); |
++++symlink函数创建一个符号链接,当读取该符号链接时实际上读取的是符号链接所指向的目的文件的内容;写操作的道理是一样的;如果希望读取符号链接,文件本身应当使用专门的系统函数;
++++B2.29、telldir
++++B2.29、telldir |
++B2.29、telldir
++++立钻哥哥:telldir函数返回参数所表示的目录文件目前的读取位置;
off_t telldir(DIR *dir); |
++++使用telldir函数只能够得到目录文件的读取位置,不能得到目录文件的写位置;只是由于目录文件本身并不是可写的,这一点和普通文件是不一样的;只有系统可以写一个目录文件;
++++B2.30、truncate
++++B2.30、truncate |
++B2.30、truncate
++++立钻哥哥:truncate函数改变一个文件的大小,如果新的大小小于文件的原大小,则放弃超出的部分;
int truncate(const char *pathname, off_t length); |
++++truncate函数的第二个参数表示将文件截短的字节数,超过这个字节数的部分将被系统放弃;如果文件的实际大小小于这个指定的值,则系统会自动拓展该文件;这时文件实际末尾和拓展的新末尾之间形成一个文件空洞;
++++B2.31、umask
++++B2.31、umask |
++B2.31、umask
++++立钻哥哥:umask函数设置创建文件时使用的权限掩码;mode_t类型也是一个位向量,对应9个权限标志位;哪一位的屏蔽位为1,说明用户在创建文件时所指定的权限标志无效,新文件不具有该权限;为0则相反,是否具有该权限,取决于用户的权限字;
mode_t umask(mode_t cmask); |
++++运行的mask程序时Shell进程的子进程,子进程改变父进程的环境,从安全的角度来讲是不应该的;因此umask函数更改进程环境下的创建文件时使用的权限掩码并不影响父进程;
++++B2.32、unlink
++++B2.32、unlink |
++B2.32、unlink
++++立钻哥哥:unlink函数将pathname最末端的目录项删除,并且将该目录项所对应的的磁盘文件的链接数键1;
int unlink(const char *pathname); |
++++使用unlink函数应当注意,即使一个文件的链接数已经为0,只要该文件打开,程序仍可以引用该文件;包括对文件的读和写,不过这时的读写操作实际上是在对内存中缓冲区进行操作;当文件被关闭时,内存中的缓冲区消失,文件也就消失了;
++B3、标准I/O函数
++B3、标准I/O函数 |
++B3、标准I/O函数
++++立钻哥哥:Linux/UNIX下的I/O函数主要使用在磁盘文件操作上,以及标准I/O文件(标准输出,标准输入等);系统中同时还为临时数据文件提供了一些相应的操作函数;
++++B3.1、clearerr
++++B3.2、fclose
++++B3.3、fdopen
++++B3.4、feof
++++B3.5、fflush
++++B3.6、fgetc
++++B3.7、fgetpos
++++B3.8、fgets
++++B3.9、fileno
++++B3.10、fopen
++++B3.11、fputc
++++B3.12、fputs
++++B3.13、fread
++++B3.14、freopen
++++B3.15、fseek
++++B3.16、fsetpos
++++B3.17、ftell
++++B3.18、fwrite
++++B3.19、getc
++++B3.20、getchar
++++B3.21、gets
++++B3.22、mktemp
++++B3.23、putc
++++B3.24、putchar
++++B3.25、puts
++++B3.26、rewind
++++B3.27、setbuf
++++B3.28、setbuffer
++++B3.29、setlinebuf
++++B3.30、setvbuf
++++B3.31、tmpfile
++++B3.32、ungetc
&&Tips:这篇博文暂时拓展到这里了,有些不舍,但必须中断了,有兴趣的可以查看以下链接拓展:
++++【C/C++函数与算法(C库独立篇)】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104026090
++++【Linux系统编程】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9694767.html
++++【C++C铸就生存利器】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9325802.html
++++【人工智能AI2026】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9212024.html
++++【立钻哥哥优快云空间】:https://blog.youkuaiyun.com/VRunSoftYanlz/

@@提示:有些博客可能只是开了头,如果感兴趣的同学,可以“点赞”或“评论区留言”,只要关注的同学多了,那就会继续完善哟!(“++==”,表示没有写完的,如果关注度不高就不完善了;“++ok++”,表示此篇博客已经完成,是阶段性完整的!)

++++VR云游戏=Unity+SteamVR+云技术+5G+AI;(说明:AI人工智能不是我们的主要研究技术,只是了解一下,领略一下有风的感觉!但是,VR是我们的研究重点)
++++【Linux系统编程】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9694767.html
++++【Linux从入门到放弃】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104176967
++++【Linux C函数与算法】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104076473
++++【Linux系统编程】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104151861
++++【Linux内核API】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104189074
++++【Linux内核剖析】:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/104200535
++++【C++C铸就生存利器】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9325802.html
++++【人工智能AI2026】分类:https://blog.youkuaiyun.com/vrunsoftyanlz/category_9212024.html
++++【立钻哥哥优快云空间】:https://blog.youkuaiyun.com/VRunSoftYanlz/

【XR游戏开发QQ群:784477094】

++立钻哥哥推荐的拓展学习链接(Link_Url):
| 立钻哥哥推荐的拓展学习链接(Link_Url) |
++++立钻哥哥Unity 学习空间: http://blog.youkuaiyun.com/VRunSoftYanlz/
++++虚拟现实VR资讯: https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89165846
++++HTC_VIVE开发基础:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81989970
++++Oculus杂谈:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82469850
++++Oculus安装使用:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82718982
++++Unity+SteamVR=>VR:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/88809370
++++Unity减少VR晕眩症:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89115518
++++SteamVR简介:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/86484254
++++SteamVR脚本功能分析:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/86531480
++++SteamVR2.0开发指南:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/86618187
++++SteamVR2.2.0开发指南:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/88784527
++++SteamVR2.2.0快速入门:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/88833579
++++SteamVR2.2.0交互系统:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89199778
++++SteamVR2.2.0传送机制:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89390866
++++SteamVR2.2.0教程(一):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89324067
++++SteamVR2.2.0教程(二):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89894097
++++SteamVR_Skeleton_Poser:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89931725
++++SteamVR实战之PMCore:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89463658
++++SteamVR/Extras:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/86584108
++++SteamVR/Input:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/86601950
++++OpenXR简介:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/85726365
++++VRTK杂谈:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82562993
++++VRTK快速入门(杂谈):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82955267
++++VRTK官方示例(目录):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82955410
++++VRTK代码结构(目录):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82780085
++++VRTK(SceneResources):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82795400
++++VRTK_ControllerEvents:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83099512
++++VRTK_InteractTouch:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83120220
++++虚拟现实行业应用:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/88360157
++++Steam平台上的VR:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/88960085
++++Steam平台热销VR:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/89007741
++++VR实验:以太网帧的构成:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82598140
++++实验四:存储器扩展实验:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/87834434
++++FrameVR示例V0913:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82808498
++++FrameVR示例V1003:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83066516
++++SwitchMachineV1022:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83280886
++++PlaySceneManagerV1022:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83280886
++++Unity5.x用户手册:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81712741
++++Unity面试题ABC:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78630687
++++Unity面试题D:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/78630838
++++Unity面试题E:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78630913
++++Unity面试题F:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/78630945
++++Cocos2dx面试题:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/78630967
++++禅道[zentao]:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83964057
++++Lua快速入门篇(Xlua拓展):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81173818
++++Lua快速入门篇(XLua教程):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81141502
++++Lua快速入门篇(基础概述):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81041359
++++框架知识点:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/80862879
++++游戏框架(UI框架夯实篇):https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/80781140
++++游戏框架(初探篇):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/80630325
++++.Net框架设计:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/87401225
++++从零开始学架构:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/88095895
++++设计模式简单整理:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/79839641
++++专题:设计模式(精华篇):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81322678
++++U3D小项目参考:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/80141811
++++Unity小游戏算法分析:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/87908365
++++Unity案例(Vehicle):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82355876
++++UML类图:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/80289461
++++PowerDesigner简介:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/86500084
++++Unity知识点0001:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/80302012
++++Unity知识点0008:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81153606
++++U3D_Shader编程(第一篇:快速入门篇):https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/80372071
++++U3D_Shader编程(第二篇:基础夯实篇):https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/80372628
++++Unity引擎基础:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78881685
++++Unity面向组件开发:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78881752
++++Unity物理系统:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78881879
++++Unity2D平台开发:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78882034
++++UGUI基础:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78884693
++++UGUI进阶:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78884882
++++UGUI综合:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78885013
++++Unity动画系统基础:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78886068
++++Unity动画系统进阶:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78886198
++++Navigation导航系统:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78886281
++++Unity特效渲染:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78886403
++++Unity数据存储:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/79251273
++++Unity中Sqlite数据库:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/79254162
++++WWW类和协程:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/79254559
++++Unity网络:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/79254902
++++Unity资源加密:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/87644514
++++PhotonServer简介:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/86652770
++++编写Photon游戏服务器:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/86682935
++++C#事件:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78631267
++++C#委托:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78631183
++++C#集合:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78631175
++++C#泛型:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78631141
++++C#接口:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78631122
++++C#静态类:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78630979
++++C#中System.String类:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78630945
++++C#数据类型:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78630913
++++Unity3D默认的快捷键:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78630838
++++游戏相关缩写:https://blog.youkuaiyun.com/vrunsoftyanlz/article/details/78630687
++++UnityAPI.Rigidbody刚体:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81784053
++++UnityAPI.Material材质:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81814303
++++UnityAPI.Android安卓:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81843193
++++UnityAPI.AndroidJNI安卓JNI:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81879345
++++UnityAPI.Transform变换:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/81916293
++++UnityAPI.WheelCollider轮碰撞器:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82356217
++++UnityAPI.Resources资源:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83155518
++++JSON数据结构:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82026644
++++CocosStudio快速入门:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82356839
++++Unity企业内训(目录):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82634668
++++Unity企业内训(第1讲):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82634733
++++Unity企业内训(第2讲):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82861180
++++Unity企业内训(第3讲):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82927699
++++Unity企业内训(第4讲):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83479776
++++Unity企业内训(第5讲):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83963811
++++Unity企业内训(第6讲):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/84207696
++++钻哥带您了解产品原型:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/87303828
++++插件<Obi Rope>:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/83963905
++++计算机组成原理(教材篇):https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/82719129
++++5G接入:云计算和雾计算:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/88372718
++++云计算通俗讲义:https://blog.youkuaiyun.com/VRunSoftYanlz/article/details/88652803
++++立钻哥哥Unity 学习空间: http://blog.youkuaiyun.com/VRunSoftYanlz/
--_--VRunSoft:lovezuanzuan--_--





被折叠的 条评论
为什么被折叠?



