Linux高级编程_27_系统调用

news2024/11/15 13:29:42

文章目录

  • 系统调用
    • 函数分类
    • 系统编程概述
    • 系统调用概述
      • **类UNIX系统的软件层次**
    • 用户态和内核态
    • 系统调用与库函数的关系
    • 文件操作符
      • 概述
      • 文件磁盘权限
    • 系统调用之文件操作
      • open:打开文件
      • close:关闭文件
      • write:写入
      • read:读取
    • 文件状态
      • fcntl 函数
      • stat 函数
    • st_mode的值
        • 示例 1:
        • 示例 2:只写和追加
        • 示例 3: 写文件
        • 示例 4: 读文件
    • 文件夹操作
    • opendir
    • readdir
        • 示例:遍历文件夹
    • closedir

系统调用

函数分类

  • 库函数
    • 系统提供的,不能直接访问内核的 如fopen
  • 系统调用
    • 系统提供的,可以直接访问内核 如 open
  • 自定义函数
    • 自己编写的

注意

man命令:查看帮助手册

  • 章节1 查命令 例: man 1 ls

  • 章节2 系统调用 man 2 open

  • 章节3 库函数 man 3 fopen

系统编程概述

操作系统的职责

   操作系统用来管理所有的资源,并将不同的设备和不同的程序关联起来。

什么是 Linux 系统编程

  在有操作系统的环境下编程,并使用操作系统提供的系统调用及各种库,对系统资源进行访问。
  学会了C 语言再知道一些使用系统调用的方法,就可以进行Linux 系统编程了,

简单说 就是使用软件操控系统硬件以及资源 比如 灯亮…

系统调用概述

系统调用是操作系统提供给用户程序的一组“特殊”函数接口。

类UNIX系统的软件层次

在这里插入图片描述

在这里插入图片描述

用户态和内核态

引入

>	CPU 指令是可以直接操作硬件的,要是因为指令操作的不规范,造成的错误是会影
响整个 计算机系统 的。好比你写 一个程序,但是因为你对 硬件操作 不熟悉,出现
问题,那么影响范围是多大?是整个计算机系统,操作系统内核、及其其他所有正在运
行的程序,都会因为你操作失误而受到不可挽回的错误,那么你只有重启整个计算机才
行
>	而对于 硬件的操作 是非常复杂的,参数众多,出问题的几率相当大,必须及其谨
慎的进行操作,这对于个人开发者来说是个艰巨的任务,同时个人开发者在这方面也是
不被信任的。所以 操作系统内核 直接屏蔽了个人开发者对于硬件操作的可能.
>   这方面 系统内核 对 硬件操作 进行了封装处理,对外提供标准函数库,操作更简
单、更安全。比如 我们要打开一个文件,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在收到中断请求后,会立即暂停当前正在执行的任务,进入中断处理程序中处理中断请求。硬件中断具有实时性强、可靠性高、处理速度快等特点。
		如当点击按钮扫描系统高低电频时等

系统调用与库函数的关系

在这里插入图片描述

注意:

系统调用是需要时间的,程序中频繁的使用系统调用会降低程序的运行效率。当运行内核代码时,CPU工作在内核态,在系统调用发生前需要保存用户态的栈和内存环境,然后转入内核态工作。系统调用结束后,又要切换回用户态。这种环境的切换会消耗掉许多时间。

文件操作符

概述

>	文件描述符是一个非负整数,代表已打开的文件。
	每一个进程都会创建一张文件描述符表 记录的是当前进程打开的所有文件描述符。
	每一个进程默认打开三个文件描述符:
	0(标准输入设备scanf)
	1(标准输出设备printf)
	2(标准错误输入设备perror)。
	新打开的文件描述符 为最小可用文件描述符

在这里插入图片描述

扩展

ulimit是一个计算机命令,用于shell启动进程所占用的资源,可用于修改系统资源限
制。使用ulimit命令用于临时修改资源限制,如果需要永久修改需要将设置写入配置文
件/etc/security/limits.conf。
	ulimit -a 查看open files打开的文件最大数。
	
	ulimit -n 最大数 设置open files打开的文件最大数。

文件磁盘权限

在这里插入图片描述

第一位d 说是 文件还是文件夹
2~4位说明	所有者权限
5~7位说明	同组用户权限
8~10位说明其他用户权限
r   4
w   2
x   1
只读   	4 
只写       2  
只执行     1
可读可写    6
可读可执行	5
可读可写可执行  7

系统调用之文件操作

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:关闭文件

0 代表标准输入(stdin),

1 代表标准输出(stdout),

2 代表标准错误输出(stderr),

例如: close(0);表示 标准输入禁用

所需头文件
	#include<unistd.h>
函数
		int close(int fd);
参数
		关闭的文件描述符
 返回值
			成功:0
			失败:-1,并设置errno

write:写入

所需头文件
	#include <unistd.h>
函数
	ssize_t write(int fd, const void *buf, size_t count);
参数
	fd:写入的文件描述符
	buf:写入的内容首地址
	count:写入的长度,单位字节
返回值
	成功:返回写入的内容的长度,单位字节
	失败:-1	

read:读取

所需头
		#include <unistd.h>
函数
		ssize_t read(int fd,void *buf,size_t count);
参数:
		fd:文件描述符
		buf:内存首地址
		count:读取的字节个数
返回值:
		成功:实际读取到的字节个数
		失败:-1

读取完的依据:

返回值 小于 设定的每次读取的字节数

文件状态

fcntl 函数

作用:
	针对已存在的文件描述符设置阻塞状态
语法:
	所需头文件:
			#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)               

stat 函数

作用:
获取文件状态信息
所需头

#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:失败

注意:
	当文件是一个符号链接时
		lstat返回的是该符号链接本身的信息。
		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; //最后一次改变时间(指属性)
};   

st_mode的值

在这里插入图片描述

示例 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[])
{
    // O_TRUNC  覆盖清空 O_RDONLY 只读   O_WRONLY 只写  
    int f01 = open("./a.txt", O_RDONLY | O_WRONLY | O_CREAT | O_TRUNC, 0664);
    if (f01 < 0)
    {
        printf("打开失败!\n");
        return 0;
    }
    printf("end \tf01=%d\n", f01); // 3   因为0 1 2 被占用
    int flag = close(f01);
    printf("flag = %d\n", flag);
    if (flag < 0)
    {
        printf("关闭失败\n");
    }
    else
    {
        printf("关闭成功\n");
    }
    return 0;
}

在这里插入图片描述

示例 2:只写和追加
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
    // 关闭标准输入流
    close(0);
    // 权限是 只写 和追加 方式 打开
    int fd = open("./a.txt", O_WRONLY | O_APPEND );
    printf("fd = %d\n",fd); //此时打印的fd是0,证明返回的是最小可用描述符
    char *str = "你好\n";
    write(fd, str, strlen(str));
    close(fd); // 关闭文件
    return 0;
}
示例 3: 写文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    char *str  = "hello , 系统调用\n"; // 此处中文占了3字节  但是一般中文占2~4  具体视情况而定
    //参数1: 写入的文件描述符 
    //参数2: 写入的内容首地址 
    //参数3: 写入的长度,单位字节
    //成功:返回写入的内容的长度,单位字节 失败:-1
    int t = write(1,str,strlen(str));   // strlen 测长度 不算 \0
    printf("xxz = %d\n",t);
    return 0;
}

在这里插入图片描述

示例 4: 读文件
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
    char str[50] = {0};
    // 参数一: 文件描述符
    // 参数二: 内存首地址
    // 参数三: 读取的字节个数
    // 返回值: 成功:实际读取到的字节个数   失败:-1
    read(0, str, 50);  // 0 标准输入
    printf("num = %s\n",str);
    return 0;
}

文件夹操作

遍历文件夹很重要

opendir

打开目录

> 作用:打开目录 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 文件类型未知。
示例:遍历文件夹
#include <stdio.h>
#include <string.h>
//   遍历  家目录  文件夹
// 打开文件夹所需头文件
#include <sys/types.h>
#include <dirent.h>
void blDIR(char *dirPATH)
{
    DIR *d = opendir(dirPATH);   // 打开文件夹
    //返回指向该目录结构体指针(DIR *)
    if (d == NULL)
    {
        printf("打开失败\n");
        return 0;
    } // 打开成功 使用递归开始遍历
    while (1)
    {
        struct dirent *d2 = readdir(d);
        if (d2 == NULL)
        {
            break;
        }
        if (d2->d_type == DT_DIR)
        {
            if (strcmp(d2->d_name,".") == 0 || strcmp(d2->d_name,"..") == 0) 
            {//遇到文件有. 和.. 的 就暂不执行本次循环
                continue; // 跳出本次循环
            }
            char path[500] = {0};
             //追加操作 将dirent 内容追加到 path尾部
            strcat(path,dirPATH);  
            strcat(path,"/");
            strcat(path,d2->d_name); 
            // printf("=======\n");
            printf("%s\n",path);
            blDIR(path);          
        }
        else if (d2->d_type == DT_REG) // 类型要是文件
        {
            printf("%s\n",d2->d_name);
        }
    }
    closedir(d);// 关闭文件d   
}
int main(int argc, char const *argv[])
{
    blDIR("/home/xxz/");
    return 0;
}

closedir

关闭目录

> 作用:关闭目录 closedir
所需头文件
		#include <sys/types.h>
		#include <dirent.h>
函数
		int closedir(DIR *dirp);
参数:
		dirp:opendir 返回的指针
返回值:
		成功:0
	失败:-1

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

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

相关文章

光通信——FTTx

目录 FTTH模式 FTTO模式 FTTR模式 FTTB/CLAN/xDSL模式 FTTCabxDSL模式 根据接入光纤到用户的距离分类&#xff0c;PON可应用于光纤到交接箱&#xff08;FTTCab&#xff09;、光纤到大楼/路边&#xff08;FTTB/C&#xff09;、光纤到办公室&#xff08;FTTO&#xff0…

鸿蒙harmonyos next flutter混合开发之开发package

​​​​​​ 创建 package flutter create --templatepackage mypackage package代码如下&#xff1a; 创建hello_world.dart ///HelloWorld返回hello world 拼接param class HelloWorld {String helloWorld(String param) > "hello world ${param}"…

[Linux] Linux 的进程如何调度——Linux的 O(1)进程调度算法

标题&#xff1a;[Linux] Linux 的进程如何调度——优先级与进程调度 个人主页水墨不写bug 目录 一、前言 二、将要出现的概念 1.进程调度队列 2.位图 3.进程的优先级 三、Linux进程的调度过程 1.活动队列&#xff08;*active指向的队列&#xff09; 2.过期队列&#…

Linux的多线程(线程的创建,退出,取消请求,取消处理例程,线程属性的设置)

进程:是系统分配资源的最小单位,系统会为每一个进程分配一块独立的虚拟内存空间 线程:是系统调度的最小单位,系统不会为线程分配新的内存空间,但是线程也参与系统调度 cpu把时间片分给每一个进程&#xff0c;进程中的时间片再切分分给每一个线程&#xff0c;所以线程也会得到…

在掌控板中加载人教版信息科技教学指南中的educore库

掌控板中加载educore库 人教信息科技数字资源平台&#xff08;https://ebook.mypep.cn/free&#xff09;中的《信息科技教学指南硬件编程代码说明》文件中提到“本程序说明主要供教学参考。需要可编程主控板须支持运行MicroPython 脚本程序。希望有更多的主控板在固件中支持ed…

【重学 MySQL】五十二、MySQL8 新特性:计算列

【重学 MySQL】五十二、MySQL8 新特性&#xff1a;计算列 定义特性用法应用场景注意事项 在MySQL8中&#xff0c;计算列是一项引入的新特性&#xff0c;它为数据处理和分析提供了更大的灵活性和便捷性。 定义 计算列是指根据数据库中其他列的值通过计算得出的新列&#xff0c…

网站开发基础:HTML、CSS

前端开发主要使用的技术如 HTML、CSS 和 JavaScript 等。 简单制作一个网页 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>柒毓同学网站的首页</title><style>.c1{border: solid …

OpenGL笔记十九之相机系统

OpenGL笔记十九之相机系统 —— 2024-10-02 晚上 文章目录 OpenGL笔记十九之相机系统1.运行1.1.游戏相机1.2.轨迹球相机 2.游戏相机与轨迹球相机切换3.博主笔记本要运行需要更改的文件更改1:28_OpenGL_CameraSystem/application/Application.cpp更改2:28_OpenGL_CameraSystem/a…

YOLOv8改进,YOLOv8改进主干网络为GhostNetV3(2024年华为的轻量化架构,全网首发),助力涨点

摘要 GhostNetV3 是由华为诺亚方舟实验室的团队发布的,于2024年4月发布。 摘要:紧凑型神经网络专为边缘设备上的应用设计,具备更快的推理速度,但性能相对适中。然而,紧凑型模型的训练策略目前借鉴自传统模型,这忽略了它们在模型容量上的差异,可能阻碍紧凑型模型的性能…

查找与排序-归并排序

排序算法可以分为内部排序和外部排序&#xff0c; 内部排序是数据记录在内存中进行排序&#xff0c; 外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要访问外存。 常见的内部排序算法有&#xff1a;插入排序、希尔排序、选择…

Arduino UNO R3自学笔记16 之 Arduino的定时器介绍及应用

注意&#xff1a;学习和写作过程中&#xff0c;部分资料搜集于互联网&#xff0c;如有侵权请联系删除。 前言&#xff1a;学习定时器的功能。 1.定时器介绍 定时器也是一种中断&#xff0c;属于软件中断。 它就像一个时钟&#xff0c;可以测量事件的时间间隔。 比如早…

操作系统学习笔记---文件管理

文件系统基础 概念 文件&#xff1a;以计算机硬盘为载体的存储在计算机上的信息集合 文件的属性 文件具有一定的属性&#xff0c;系统不同&#xff0c;属性也会有所不同&#xff0c;但通第都包括如下属性&#xff1a;名称、标识符、类型、位置、大小、保护、时间、日期和用…

vbs读取excel内容的代码-编辑代码,查找并在以下位置xls文件路径-供大家学习研究参考

用vbs读取excel的脚本&#xff0c;比较强悍。 编辑代码,查找并在以下位置xls文件路径。 strExcelPath "xls文件的路径" 当然&#xff0c;要想正确运行&#xff0c;你需得安装ms excel才行。 下载&#xff1a;https://download.csdn.net/download/weixin_43097956/…

【数据分享】2000—2023年我国省市县三级逐月植被覆盖度(FVC)数值(Shp/Excel格式)

之前我们分享过2000—2023年我国250米分辨率逐月植被覆盖度&#xff08;FVC&#xff09;栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff0c;该数据来源于高吉喜等学者在国家青藏高原科学数据中心平台上分享的数据&#xff0c;合成方式采用月最大值合成&…

命令按钮QLink

主要作用用来点击后可以自动打开系统的网页浏览器&#xff0c;跳转到指定的网页 常用方法 文本 //获取和设置文本 QString text() const void setText(const QString &text)描述信息 //获取和设置描述文本 QString description() const void setDescription(const QSt…

YOLOv11改进 | 注意力篇 | YOLOv11引入ACmix注意力机制

1. ACmix介绍 1.1 摘要&#xff1a;卷积和自注意力是表示学习的两种强大技术&#xff0c;它们通常被认为是两种彼此不同的同行方法。 在本文中&#xff0c;我们表明它们之间存在很强的潜在关系&#xff0c;从某种意义上说&#xff0c;这两种范式的大量计算实际上是通过相同的操…

特殊的加法和除法(考察点为位操作符)

目录 一简介&#xff1a; 二例题讲解&#xff1a; 2.1不用加号的加法&#xff1a; 2.1.1题目&#xff1a; 2.1.2思路汇总&#xff1a; 2.1.3代码解答&#xff1a; 2.2两数相除&#xff1a; 2.2.1题目&#xff1a; 2.2.2思路汇总&#xff1a; 2.2.3代码解答&#xff1a…

第 13 章 常用类

第 13 章 常用类 文章目录 <center>第 13 章 常用类13.1 包装类13.1.1 包装类的分类13.1.2 包装类和基本数据的转换13.1.3 案例演示13.1.4 课堂测试题13.1.5 包装类型和 String 类型的相互转换13.1.6 Integer 类和 Character13.1.7 Integer 类面试题 113.1.8 Intege 类面…

【算法】0/1背包问题

背包中有一些物品&#xff0c;每件物品有它的价值与重量&#xff0c;给定一个重量&#xff0c;在该重量范围内取物品&#xff08;每件物品不可重复取&#xff09;&#xff0c;求最大价值。 将需求转化为表格&#xff0c;每一行中的每个格子代表可选哪些下标的物品在总重量限额内…

【c++】 模板初阶

泛型编程 写一个交换函数&#xff0c;在学习模板之前&#xff0c;为了匹配不同的参数类型&#xff0c;我们可以利用函数重载来实现。 void Swap(int& a, int& b) {int c a;a b;b c; } void Swap(char& a, char& b) {char c a;a b;b c; } void Swap(dou…