Linux高级系统编程中的系统调用

概念

是操作系统提供给用户使其可以操作内核提供服务的一组函数接口。

用户态和内核态:

引入
        整个 计算机系统 的。好比你写 一个程序,但是因为你对 硬件操作 不熟悉,出现 问题,那么影响范围是多大?是整个计算机系统,操作系统内核、及其其他所有正在运 行的程序,都会因为你操作失误而受到不可挽回的错误,那么你只有重启整个计算机才 行 而对于 硬件的操作 是非常复杂的,参数众多,出问题的几率相当大,必须及其谨 慎的进行操作,这对于个人开发者来说是个艰巨的任务,同时个人开发者在这方面也是 不被信任的。所以 操作系统内核 直接屏蔽了个人开发者对于硬件操作的可能.
        这方面 系统内核 对 硬件操作 进行了封装处理,对外提供标准函数库,操作更简 单、更安全。比如 我们要打开一个文件,C 标准函数库中对应的是 fopen() ,其内部封 装的是内核中的系统函数open() 因为这个需求,硬件设备商直接提供了硬件级别的支持,做法就是对 CPU 指令设置了 权限,不同级别的权限可以使用的 CPU 指令是有限制的。以 Inter CPU 为例, Inter 把 CPU 指令操作的权限划为 4 级:
        ring 0
        ring 1
        ring 2
        ring 3
        其中 ring 0 权限最高,可以使用所有 CPU 指令, ring 3 权限最低,仅能使用 常规 CPU 指令,这个级别的权限不能使用访问硬件资源的指令,比如 IO 读写、网卡 访问、申请内存都不行,都没有权限
        Linux 系统内核采用了: ring 0 ring 3 2 个权限
ring 0:
        内核态 , 完全在 操作系统内核 中运行,由专门的 内核线程 在 CPU 中 执行其任务
ring 3:
        用户态 , 在 应用程序 中运行,由 用户线程 在 CPU 中执行其任务 Linux 系统中所有对硬件资源的操作都必须在 内核态 状态下执行,比如 IO 的 读写,网络的操作
区别
        1,用户态的代码必须由 用户线程 去执行、内核态的代码必须由 内核线程 去执行
        2,用户态、内核态 或者说 用户线程、内核线程 可以使用的资源是不同的,尤体现在 内存资源上。Linux 内核对每一个进程都会分配 4G 虚拟内存空间地址
        用户态: --> 只能操作 0-3G 的内存地址
        内核态: --> 0-4G 的内存地址都可以操作,尤其是对 3-4G 的高位地址必须由 内核态去操作,因为所有进程的 3-4G 的高位地址使用的都是同一块、专门留给 系统 内核 使用的 1G 物理内存
        3.所有对 硬件资源、系统内核数据 的访问都必须由内核态去执行
如何切换内核态
        通过软件中断
软件中断
        软件中断是由软件程序触发的中断,如系统调用、软中断、异常等。软件中断不是 由硬件设备触发的,而是由软件程序主动发起的,一般用于系统调用、进程切换、异常 处理等任务。软件中断需要在程序中进行调用,其响应速度和实时性相对较差,但是具 有灵活性和可控性高的特点。
        如程序中出现的内存溢出, 数组下标越界等
硬件中断
        硬件中断是由硬件设备触发的中断,如时钟中断、串口接收中断、外部中断等。当 硬件设备有数据或事件需要处理时,会向CPU 发送一个中断请求, CPU 在收到中断请求 后,会立即暂停当前正在执行的任务,进入中断处理程序中处理中断请求。硬件中断具 有实时性强、可靠性高、处理速度快等特点。
        如当点击按钮扫描系统高低电频时等

系统调用与库函数的关系

库函数可以调用系统调用提供的接口 , 也可以不调用系统调用提供的接口
        不调用系统调用的库函数:strcpy,bzero
        调用系统调用的库函数:fread,printf
注意 :
        系统调用是需要时间的,程序中频繁的使用系统调用会降低程序的运行效率。当运行内核 代码时,CPU 工作在内核态,在系统调用发生前需要保存用户态的栈和内存环境,然后转 入内核态工作。系统调用结束后,又要切换回用户态。这种环境的切换会消耗掉许多时 间。

文件操作

文件描述符概念

        文件描述符是一个非负整数, 代表已打开的文件。
        每一个进程都会创建一张文件描述符表 记录的是当前进程打开的所有文件描述符。
        每一个进程默认打开三个文件描述符:
        0(标准输入设备 scanf)
        1(标准输出设备 printf)
        2(标准错误输入设备 perror)
        新打开的文件描述符 为最小可用文件描述符。
扩展
        ulimit是一个计算机命令,用于 shell 启动进程所占用的资源,可用于修改系统资源限 制。使用ulimit 命令用于临时修改资源限制,如果需要永久修改需要将设置写入配置文 件/etc/security/limits.conf
        ulimit -a 查看 open files 打开的文件最大数。
        ulimit -n 最大数 设置 open files 打开的文件最大数。

文件读写

第一位说是文件还是文件夹
        2~4位说明所有者权限
        5~7位说明同组用户权限
        8~10位说明其他用户权限
        r 4
        w 2
        x 1
注意
        man 2 系统调用
        查看系统调用函数对应的头文件与函数信息
语法 :
open: 打开文件
所需头文件
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <fcntl.h>
函数
        int open(const char *pathname, int flags);
        int open(const char *pathname, int flags, mode_t mode);
参数
        pathname:打开的文件地址
        flags:代码操作文件的权限
必选项
        O_RDONLY 以只读的方式打开
        O_WRONLY 以只写的方式打开
        O_RDWR 以可读、可写的方式打开
可选项
        O_CREAT 文件不存在则创建文件,使用此选项时需使用 mode 说明文件的权限
        O_EXCL 如果同时指定了 O_CREAT ,且文件已经存在 , 则打开 , 如果文件 不存在则新建
        O_TRUNC 如果文件存在,则清空文件内容
        O_APPEND 写文件时,数据添加到文件末尾
        O_NONBLOCK 对于设备文件 , O_NONBLOCK 方式打开可以做非阻塞 I/O
mode: 文件在磁盘中的权限
格式 :
        0ddd
        d的取值 :4( 可读 ),2( 可写 ),1( 可执行 )
第一个 d: 所有者权限
第二个 d: 同组用户权限
第三个 d: 其他用户权限
如果需要可读可写就是 6, 可读可执行 5
:
        0666:所有者可读可写 , 同组用户可读可写 , 其他用户可读可写
        0765:所有者可读可写可执行 , 同组用户可读可写 , 其他用户可读可执行
返回值:
        成功:得到最小可用的文件描述符
        失败:-1
经验 :
        操作已有文件使用两参
        新建文件使用三参
close 关闭文件
所需头文件
        #include <unistd.h>
函数
        int close(int fd);
参数
        关闭的文件描述符
返回值
        成功:0
        失败: -1, 并设置 errno
示例 : 以只读的方式打开关闭文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{//1打开文件// man 2 系统调用函数名// int open(const char *pathname, int flags);// int open(const char *pathname, int flags, mode_t mode);int fileTag = open("a.txt",O_RDONLY);if (fileTag < 0){printf("读取文件不存在,文件标识符为:%d\n",fileTag);return 0;}printf("文件打开成功,文件标识符为:%d\n",fileTag);int tag = close(fileTag);if (tag < 0){printf("关闭文件失败\n");}else{printf("关闭文件成功\n");}return 0;
}
示例 : 以写的方式打开关闭文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{//1打开文件// man 2 系统调用函数名// int open(const char *pathname, int flags);// int open(const char *pathname, int flags, mode_t mode);int fileTag = open("a.txt",O_WRONLY| O_CREAT, 0644);if (fileTag < 0){printf("文件不存在,文件标识符为:%d\n",fileTag);return 0;}printf("文件打开成功,文件标识符为:%d\n",fileTag);int tag = close(fileTag);if (tag < 0){printf("关闭文件失败\n");}else{printf("关闭文件成功\n");}return 0;
}
write 写入
所需头文件
        #include <unistd.h>
函数
        ssize_t write(int fd, const void *buf, size_t count);
参数
        fd:写入的文件描述符
        buf:写入的内容首地址
        count:写入的长度 , 单位字节
返回值
        成功: 返回写入的内容的长度 , 单位字节
        失败:-1
示例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{int fileTag = open("a.txt",O_WRONLY| O_CREAT | O_APPEND, 0744);if (fileTag < 0){printf("文件不存在,文件标识符为:%d\n",fileTag);return 0;}char str[] = "hello";int len = write(fileTag,str,sizeof(str)-1);if(len < 0){printf("写入失败\n");}else{printf("写入成功len = %d,%d\n",len,sizeof(str));}int tag = close(fileTag);if (tag < 0){printf("关闭文件失败\n");}else{printf("关闭文件成功\n");}return 0;
}
read 读取
所需头
        #include <unistd.h>
函数
        ssize_t read(int fd, void *buf, size_t count);
参数:
        fd:文件描述符
        buf:内存首地址
        count:读取的字节个数
返回值:
        成功: 实际读取到的字节个数
        失败:-1
示例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{int id = open("a.txt",O_RDONLY);if(id < 0){printf("文件打开失败\n");return 0;}char buf[50] = "";int len = read(id,buf,sizeof(buf));printf("%s",buf);if (close(id) < 0){printf("文件关闭失败\n");}return 0;
}
示例 : 文件复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{int fd_r = open("a.txt",O_RDONLY);if(fd_r < 0){printf("读取文件打开失败\n");return 0;}int fd_w = open("b.txt",O_WRONLY|O_CREAT|O_APPEND,0666);if(fd_w < 0){printf("写入文件打开失败\n");return 0;}while (1){char buf[3] = "";int len = read(fd_r,buf,sizeof(buf));int size = write(fd_w,buf,len);if (len < sizeof(buf)){break;}}if (close(fd_w) < 0){printf("写入文件关闭失败\n");}if (close(fd_r) < 0){printf("读取文件关闭失败\n");}printf("OVER\n");return 0;
}

文件的阻塞特性

        read默认为阻塞。如果读不到数据,将阻塞不继续执行 知道有数据可读,才继续往下 执行。
        非阻塞特性:如果没数据,立即返回,继续执行。
        注意: 阻塞与非阻塞是对于文件而言的,而不是指 read write 等的属性。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{//dev:liunx设备存储文件夹//tty:终端///dev/tty:表示当前终端int fd = open("/dev/tty",O_RDONLY);//O_NONBLOCK:设置打开的文件为非阻塞// int fd = open("/dev/tty",O_RDONLY|O_NONBLOCK);char buf[32] = "";printf("开始读取\n");read(fd,buf,sizeof(buf));printf("读取结束\n");return 0;
}
通过 open 打开的文件可以设置非阻塞 , 但是如果不是通过 open 打开的文件怎么办 ?
通过 fcntl 函数来解决
funtl
作用 : 针对已经存在的文件描述符设置阻塞状态
所需头文件
#include <unistd.h>
#include <fcntl.h>
函数 :
int fcntl(int fd, int cmd, ... /* arg */);
功能 :
改变已打开的文件性质, fcntl 针对描述符提供控制。
参数:
fd :操作的文件描述符
cmd :操作方式
arg :针对 cmd 的值, fcntl 能够接受第三个参数 int arg
返回值:
成功:返回某个其他值
失败: -1
fcntl 函数有 5 种功能:
        1) 复制一个现有的描述符( cmd=F_DUPFD
        2) 获得/设置文件描述符标记 (cmd=F_GETFD F_SETFD)
        3) 获得/设置文件状态标记 (cmd=F_GETFL F_SETFL)
        4) 获得/设置异步 I/O 所有权 (cmd=F_GETOWN F_SETOWN)
        5) 获得/设置记录锁 (cmd=FGETLK, F_SETLK F_SETLKW)
使用步骤
        1,获取文件状态标记
        2,将得到的文件状态标记设置为非阻塞
        3,将修改后的文件非阻塞状态标记 , 设置到当前文件描述符中
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
//1,获取文件标记状态
int status = fcntl(0,F_GETFL);
//2修改状态为非阻塞状态
status = status | O_NONBLOCK;
//3,设置文件标记状态为非阻塞状态
fcntl(0,F_SETFL,status);
char buf[32]="";
printf("开始读取\n");
//0(标准输入设备scanf)
int len = read(0,buf,sizeof(buf));
printf("结束读取,读取到的内容为:%s\n",buf);
return 0;
}

文件状态

语法
作用 :
        获取文件状态信息
所需头
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <unistd.h>
函数
        int stat(const char *path, struct stat *buf);
        int lstat(const char *pathname, struct stat *buf);
参数
        1参 : 文件地址
        2参 : 保存文件信息的结构体
返回值
        0:成功
        -1:失败
stat lstat 的区别
        当文件是一个符号链接时
        lstat 返回的是该符号链接本身的信息 ,
        stat 返回的是该链接指向的文件的信息。
stat 结构体解释
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬连接数目,刚建立的文件值为 1
uid_t st_uid; //用户 ID
gid_t st_gid; //组 ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
blksize_t st_blksize; //块大小(文件系统的 I/O 缓冲区大小)
blkcnt_t st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
stat 结构体 st_mode 属性
        一个由16 个字节组成 , 简称 16
        0~2其他人权限
        3~5所属组权限
        6~8所有者权限
        12~15文件类型
        具体参考下图
存储权限
S_ISUID 04000 set-user-ID bit
S_ISGID 02000 set-group-ID bit (see below)
S_ISVTX 01000 sticky bit (see below)
S_IRWXU 00700 owner has read, write, and execute permission
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRWXG 00070 group has read, write, and execute permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 others (not in group) have read, write, and execute permission
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
#include <stdio.h>
#include <sys/types.h>//open
#include <sys/stat.h>//open
#include <fcntl.h>//open
#include <unistd.h>//close
int main(int argc, char *argv[])
{
//获取文件状态
struct stat st;
stat("a.txt", &st);
//分析文件类型
if(S_ISREG(st.st_mode))
{
printf("普通文件\n");
}
else if (S_ISDIR(st.st_mode))
{
printf("目录文件\n");
}
//分析权限
if((st.st_mode & S_IRUSR) ==S_IRUSR )
{
printf("所有者具有读权限\n");
}
if((st.st_mode & S_IWUSR) ==S_IWUSR)
{
printf("所有者具有写权限\n");
}
if((st.st_mode & S_IXUSR) ==S_IXUSR)
{
printf("所有者具有执行权限\n");
}
printf("文件的大小:%ld\n", st.st_size);
return 0;
}

目录操作

语法
打开目录
作用 : 打开目录 opendir
所有头文件 :
        #include <sys/types.h>
        #include <dirent.h>
函数 :
        DIR *opendir(const char *name);
参数:
        name:目录名
返回值:
        成功:返回指向该目录结构体指针(DIR *)
        失败:NULL
DIR: 中文名称句柄 , 其实就是目录的结构体指针
读取目录
作用 : 读取目录 readdir
所需头文件
        #include <dirent.h>
函数
        struct dirent *readdir(DIR *dirp);
参数:
        dirp: opendir 的返回值
返回值:
        成功:目录结构体指针
        失败:NULL
注意 : 一次读取一个文件。
相关结构体
相关结构体说明:
struct dirent
{
        ino_t d_ino; // 此目录进入点的 inode
        off_t d_off; // 目录文件开头至此目录进入点的位移
        signed short int d_reclen; // d_name 的长度 , 不包含 NULL 字符
        unsigned char d_type; // d_type 所指的文件类型
        char d_name[256]; // 文件名
};
d_type 说明 :
DT_BLK 这是一个块设备。 ( 块设备如 : 磁盘 )
DT_CHR 这是一个字符设备。 ( 字符设备如 : 键盘 , 打印机 )
DT_DIR 这是一个目录。
DT_FIFO 这是一个命名管道( FIFO )。
DT_LNK 这是一个符号链接。
DT_REG 这是一个常规文件。
DT_SOCK 这是一个 UNIX 域套接字。
DT_UNKNOWN 文件类型未知。
关闭目录
作用 : 关闭目录 closedir
所需头文件
        #include <sys/types.h>
        #include <dirent.h>
函数
        int closedir(DIR *dirp);
参数:
        dirp:opendir 返回的指针
返回值:
        成功:0
        失败:-1
示例:扫描文件目录
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc, char const *argv[])
{
DIR *dir = opendir("./");
if(dir == NULL)
{
printf("打开文件夹失败");
return 0;
}
while(1)
{
struct dirent * d = readdir(dir);
if (d == NULL)
{
break;
}
if (d->d_type == DT_DIR)
{
printf("%s是个文件夹\n",d->d_name);
}
else if(d->d_type == DT_REG)
{
printf("%s是个普通文件\n",d->d_name);
}
}
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
void blDIR(char *path)
{
char filedir[128]="";
strcpy(filedir,path);
DIR *dir = opendir(filedir);
if(dir == NULL)
{
printf("打开文件夹失败");
return;
}
while(1)
{
struct dirent * d = readdir(dir);
if (d == NULL)
{
break;
}
/**
* strcmp(字符串1,字符串2):比较字符串是否相同
* strcat(字符串1,字符串2):将字符串2拼接到字符串1后
*/
if (d->d_type == DT_DIR && strcmp(d->d_name,".") != 0 &&
strcmp(d->d_name,"..") !=0)
{
printf("%s是个文件夹\n",d->d_name);
strcat(filedir,"/");
strcat(filedir,d->d_name);
blDIR(filedir);
}
else if(d->d_type == DT_REG)
{
printf("%s是个普通文件\n",d->d_name);
}
}
closedir(dir);
}
int main(int argc, char const *argv[])
{
blDIR("./");
return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/199839.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构(超详细讲解!!)第二十六节 图(中)

1.存储结构 1.邻接矩阵 图的邻接矩阵表示法&#xff08;Adjacency Matrix&#xff09;也称作数组表示法。它采用两个数组来表示图&#xff1a; 一个是用于存储顶点信息的一维数组&#xff1b;另一个是用于存储图中顶点之间关联关系的二维数组&#xff0c;这个关联关系数组被…

http面试题,三次握手四次挥手

在浏览器中输入网址按下回车经历了一个怎样的过程&#xff1f; 总的来说分为以下几个过程&#xff1a; 1、DNS解析&#xff1a;将域名解析为IP地址; 2、TCP连接&#xff1a;TCP三次握手; 3、发生HTTP请求; 4、服务器处理请求并返回HTTP报文; 5、浏览器解析渲染页面; 6、断开连接…

Isaac Sim教程03 Isaac Sim的基本使用

Isaac Sim 基本使用 版权信息 Copyright 2023 Herman YeAuromix. All rights reserved.This course and all of its associated content, including but not limited to text, images, videos, and any other materials, are protected by copyright law. The author holds…

CentOS服务自启权威指南:手动启动变为开机自启动(以Jenkins服务为例)

前言 CentOS系统提供了多种配置服务开机自启动的方式。本文将介绍其中两种常见的方式&#xff0c; 一种是使用Systemd服务管理器配置&#xff0c;不过&#xff0c;在实际中&#xff0c;如果你已经通过包管理工具安装的&#xff0c;那么服务通常已经被配置为Systemd服务&#…

渗透测试学习day7

文章目录 靶机&#xff1a;VaccineTask1Task2Task3Task4Task5Task6 7-9解题过程Task7Submit user flagSubmit root flag 靶机&#xff1a;Vaccine Task1 问题&#xff1a;除了SSH和HTTP&#xff0c;这个盒子上还托管了什么服务&#xff1f; ftpnmap扫一下 Task2 问题&…

【机器视觉技术栈】03 - 镜头

镜头 定焦镜头变焦镜头远心镜头 FA镜头与远心镜头的区别&#xff1f; 焦距越小畸变程度越大&#xff0c;精度要求不高的场景可以使用焦距大的FA镜头做尺寸测量&#xff0c;但焦距越大带来的问题就是整个机械设备越大。精度高的场景使用远心镜头进行尺寸测量。 光学基础知识…

Insomnia -- 非常nice的开源 API 调试工具

1. 这款开源 API 调试工具很棒&#xff01;&#xff01;&#xff01; Kong Insomnia是一个协作的开源API开发平台&#xff0c;可以轻松构建高质量的API&#xff0c;而不会像其他工具那样臃肿和混乱。 350开源插件 平衡能力和复杂性。当你需要的时候扩展工作流(当你不需要的时…

C++进阶篇7---异常

目录 一、异常的介绍 二、异常的使用 1.异常的抛出和捕获 2.异常的重新抛出 3.异常安全 4.异常规范 三、自定义异常体系 四、C标准库的异常体系 一、异常的介绍 异常是一种处理错误的方式&#xff0c;当一个函数发现自己无法处理的错误时就可以抛出异常&#xff0c;让…

LeetCode437.路径总和III

看完题目我就拿直接用递归写了如下代码&#xff1a; class Solution {private int ans;public int pathSum(TreeNode root, int targetSum) {ans 0;dfs(root, targetSum, 0);return ans;}public void dfs(TreeNode root, int targetSum, int sum){if(root null)return;sum r…

CSS面经(未完待续)

1. CSS选择器及其优先级 !important > 行内样式 > id选择器 > 类/伪类/属性选择器 > 标签/伪元素选择器 > 子/后台选择器 > *通配符 2. 重排和重绘是什么&#xff1f;浏览器的渲染机制是什么&#xff1f; 重排(回流)&#xff1a;当增加或删除dom节点&…

超大规模集成电路设计----CMOS反相器(五)

本文仅供学习&#xff0c;不作任何商业用途&#xff0c;严禁转载。绝大部分资料来自----数字集成电路——电路、系统与设计(第二版)及中国科学院段成华教授PPT 超大规模集成电路设计----CMOS反相器&#xff08;五&#xff09; 5.1 静态CMOS反相器综述5.1.1 静态CMOS反相器优点…

【C语言:自定义类型(结构体、位段、共用体、枚举)】

文章目录 1.结构体1.1什么是结构体1.2结构体类型声明1.3结构体变量的定义和初始化1.4结构体的访问 2.结构体对齐2.1如何对齐2.2为什么存在内存对齐&#xff1f; 3.结构体实现位段3.1什么是位段3.2位段的内存分配3.3位段的跨平台问题3.4位段的应用3.5位段使用注意事项 4.联合体4…

Chapter 6 Managing Application Engine Programs 管理应用程序引擎程序

Chapter 6 Managing Application Engine Programs 管理应用程序引擎程序 Running Application Engine Programs 运行应用程序引擎程序 This section provides an overview of program run options and discusses how to: 本节提供程序运行选项的概述&#xff0c;并讨论如何…

上下拉电阻会增强驱动能力吗?

最近看到一个关于上下拉电阻的问题&#xff0c;发现不少人认为上下拉电阻能够增强驱动能力。随后跟几个朋友讨论了一下&#xff0c;大家一致认为不存在上下拉电阻增强驱动能力这回事&#xff0c;因为除了OC输出这类特殊结构外&#xff0c;上下拉电阻就是负载&#xff0c;只会减…

RT-Thread Studio文件消失不见或被排除构建

不得不说RT-Thread Studio里面配置真多&#xff0c;今天我同事的电脑发现根本没有被画斜杠的文件夹&#xff0c;导致我想移植f1的写内部flash这个&#xff08;可以看上一个文章&#xff09;时候不能直接点击属性排除构建&#xff0c;然后在网上查找的时候也没怎么找到说法&…

代码随想录算法训练营 ---第五十五天

今天是 动态规划&#xff1a;编辑距离问题。 第一题&#xff1a; 简介&#xff1a; 动态规划五部曲&#xff1a; 1.确定dp数组的含义 dp[i][j] 表示以下标i-1为结尾的字符串s&#xff0c;和以下标j-1为结尾的字符串t&#xff0c;相同子序列的长度为dp[i][j]。 2.确定递推公…

智能优化算法应用:基于寄生捕食算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于寄生捕食算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于寄生捕食算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.寄生捕食算法4.实验参数设定5.算法结果6.参考…

玩转Omniverse | 将FBX文件导入Omniverse View,以及step等3D格式如何转换为USD文件的过程

1&#xff0c;参考这个过程&#xff0c;玩转Omniverse | 将FBX文件导入Omniverse View 2&#xff0c;实际操作&#xff1a; 在omniverse中安装usd explorer 打开usd explorer 选择step&#xff0c;然后右键选择convert to USD&#xff0c;点击确认&#xff0c;稍等一会就会转换…

Python神器解析时间序列数据:数据分析者必读

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 时间序列数据是在许多领域中都至关重要的数据类型&#xff0c;它涵盖了一系列按时间顺序排列的数据点。Python作为一种强大的数据分析工具&#xff0c;提供了许多库和工具&#xff0c;能够有效地处理、分析和可视…

高级搜索——伸展树Splay详解

文章目录 伸展树Splay伸展树Splay的定义局部性原理Splay的伸展操作逐层伸展双层伸展zig-zig/zag-zagzig-zag/zag-zigzig/zag双层伸展的效果与效率 伸展树的实现动态版本实现递增分配器节点定义Splay类及其接口定义伸展操作左单旋右单旋右左/左右双旋伸展 查找操作删除操作插入操…