IO / day06 作业

news2024/11/30 2:35:54

1.使用有名管道,完成两个进程的相互通信

代码:

//  使用有名管道,完成两个进程的相互通信


#include <myhead.h>


// task sender
void *tasks(void *arg)
{
	
	printf("I am tasks\n");

	int fdw = -1;
	const char **ppargv = (const char **)arg; // resolve param arg get file name
	
	printf("fifo_send=%s\n", *(ppargv + 1) );

	

	if( (fdw =open( *(ppargv +1), O_WRONLY)) == -1) 
	{
		//printf("3------\n");
		perror("fdw open error");
		return NULL;

	}
	//printf("4------\n");

	char wbuf[128] = ""; // buffer for write

	while(1)
	{

		printf("please input msg:\n");
		fgets(wbuf, sizeof(wbuf), stdin);
		wbuf[strlen(wbuf) -1] = 0;
		write(fdw, wbuf, sizeof(wbuf));

		if(strcmp(wbuf, "quit")==0)
		{
			break;
		}
	}



	close(fdw);
	printf("com closed!\n");

	pthread_exit( NULL);
}


void *taskr(void *arg)
{
	printf("I am taskr\n");

	int fdr = -1;
	const char **ppargv =(const char **)arg;
	printf("fifo_recv=%s\n", *(ppargv + 2)) ;


	if( (fdr = open( *(ppargv + 2)  , O_RDONLY)) == -1) 
	{
		//printf("1------\n");
		perror("fdr open error");
		return NULL;

	}
	char rbuf[128] = "";
	//printf("2------\n");
	

	while(1)
	{
		//printf("a------\n");

		bzero(rbuf, sizeof(rbuf));
		int res = read(fdr, rbuf, sizeof(rbuf));
		printf("received msg: %s\n", rbuf);
		if(strcmp(rbuf, "quit")==0)
		{
			break;
		}

	}
	close(fdr);

	pthread_exit( NULL);

}

int main(int argc, const char *argv[])
{
	if(argc<3)
	{
		printf("input param error\n");
		printf("usage: ./a.out fifo(send) fifo(recv)\n");
		return -1;

	}
	//char **ppargv = argv;
	//argv 是指针数组
	
	void *ppargv = (void *)argv;




	pthread_t tidr = -1;
	pthread_t tids = -1;

	if((pthread_create(&tidr, NULL, taskr,(void *) ppargv))==-1  )
	{
		printf("thread create error!\n");
		return -1;
	}

	if((pthread_create(&tids, NULL, tasks,(void *) ppargv))==-1  )
	{
		printf("thread create error!\n");
		return -1;
	}


	pthread_join(tidr, NULL);
	pthread_join(tids, NULL);


	return 0;
}

运行结果

2.使用无名管道完成父子进程间的通信

代码:

#include <myhead.h>
//使用无名管道完成父子进程间的通信

int main(int argc, const char *argv[])
{
	//define pid var
	pid_t pidr = -1;

	//define fd of pipe file array
	int pipefd[2] = {0};

	//create pipe file, ***please note this shall be done before fork().

	if(pipe(pipefd) == -1 )
	{
		perror("create pipe file error");
		return -1;
	}

	printf("pipefd[0]=%d, pipefd[1]=%d\n", pipefd[0], pipefd[1] ); //pipdfd[0]--> read; pipefd[1]-->write



	//create sub process
	pidr = fork(); // pipefd will be copied to subprocess after fork();


	if (pidr>0) // means main process
	{

		printf(">I am main process\n");

		// main process play as msg sender

		close(pipefd[0]);

		//define a write buffer
		char wbuf[128] = "";

		while(1)
		{
			printf("\t\t\t\t\tplease input a msg to send: \n");
			fgets(wbuf, sizeof(wbuf), stdin); // get inputs from terminal
			wbuf[strlen(wbuf) - 1] = 0; //remove retrun character
			write(pipefd[1], wbuf, sizeof(wbuf) ); // write to pipe file
			printf("\t\t\t\t\tmsg has been sent!\n");

			if(strcmp(wbuf, "quit")==0)
			{
				break;
			}

		}
		close(pipefd[1]);

	}
	else if(pidr == 0) // means subprocess
	{
		printf(">I am sub process\n");

		//sub process play as read, close write port
		close(pipefd[1]);


		//define a read buffer
		char rbuf[128] = "";
		sleep(3);

		while(1)
		{
			bzero(rbuf, sizeof(rbuf));	
			read(pipefd[0], rbuf, sizeof(rbuf));
			printf("recv msg:%s\n", rbuf);

			if(strcmp(rbuf, "quit")==0)
			{
				break;
			}
		}

		// close read fd of  pipe file 
		close(pipefd[0]);

		//exit sub process
		exit(EXIT_SUCCESS);


	}

	else
	{
		perror("fork error");
		return -1;

	}




	return 0;
}

运行结果


3.使用标准IO完成两个文件的拷贝

代码:

#include <myhead.h>

// 使用标准IO完成两个文件的拷贝


void cpy(const char *src, const char *dst)
{

	//define FILE ptr
	FILE *fdsrc = NULL;
	FILE *fddst = NULL;

	if( (fdsrc=fopen(src, "r")) == NULL  ) // open src file as read only
	{
		perror("src fopen error");
		return ;
	
	}

	if( (fddst=fopen(dst, "w")) == NULL  ) // open dst file as wirte only
	{
		perror("dst fopen error");
		return ;
	
	}



	while(!feof(fdsrc)) // copy until reach eof
	{
		char buf[128] = {0};
		int res =	fread(buf,  sizeof(char), sizeof(buf), fdsrc);
		fwrite(buf, sizeof(char), res, fddst); // *** shall only write what read, not buffer

	}

	fclose(fdsrc);
	fclose(fddst);


}


int main(int argc, const char *argv[])
{
	if(argc!=3)
	{
		printf("input error");
		printf("usage: ./aout srcfile, dstfile\n");

		return -1;
	
	}

	cpy(argv[1], argv[2]);



	return 0;
}

运行结果


4.使用文件IO实现两个文件的拷贝

代码:

#include <myhead.h>


void cpy(const char *src, const char *dst)
{
	//define fd
	int fdr = -1;
	int fdw = -1;

	//open file
	if( (fdr=open(src, O_RDONLY)) == -1) 
	{
		perror("open error");
		return ;
	
	}
		
			
	if( (fdw=open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0664)) == -1 )
	{
		perror("open error");
		return ;
		
	}

	//file size
	int len = lseek(fdr, 0, SEEK_END);

	//define a buffer
	char buf[8] = "";

	lseek(fdr, 0, SEEK_SET);

	while(len > 0)
	{

		int res = read(fdr, buf, sizeof(buf));
		write(fdw, buf, res);
		len -= sizeof(buf);
		//printf("buf=%s, len=%d, res=%d\n", buf, len, res);

	}

	close(fdr);
	close(fdw);
	
}

int main(int argc, const char *argv[])
{
	if(argc!=3)
	{
		printf("input error\n");
		printf("usage: ./a.out srcfile, dstfile\n");
	}

	cpy(argv[1], argv[2]);


		
	return 0;
}

运行结果


5.使用多进程完成两个文件的拷贝

代码:

#include <myhead.h>

// 使用多进程完成两个文件的拷贝

// get file size
int len(const char *src)
{
	int fds = -1;
	if( (fds=open(src, O_RDONLY))==-1   )
	{
		perror("open error");
		return -1;
	
	}

	int len = lseek(fds, 0, SEEK_END); // move cursor to the file end

	if(len==-1)
	{
		return -1;
	}

	close(fds);
	
	return len;
}

//copy func
int cpy(const char *src, const char *dst, int start, int size)
{
	int fdr = -1;
	int fdw = -1;

	if( (fdr=open(src, O_RDONLY)) == -1 )
	{
		perror("open error");
		return -1;

	}
	
	if( (fdw=open(dst, O_WRONLY )) == -1 )
	{
		perror("open error");
		return -1;

	}

	//buffer
	char buf[128] = "";

	// there are 2 processes working for copy job, 
	// move cursor to self start
	lseek(fdr, start, SEEK_SET); 
	lseek(fdw, start, SEEK_SET);

	while(size > 0 )
	{
		int res = read(fdr, buf , sizeof(buf));
		//printf("size=%d, start=%d, res=%d, buf=%s\n", size, start, res, buf);
		write(fdw, buf, res);
		size -= sizeof(size);
		
	}

	close(fdr);
	close(fdw);

	
}


int main(int argc, const char *argv[])
{

	if(argc!=3)
	{
		printf("input error\n");
		printf("usage: ./a.out srcfile, dstfile\n");
		return -1;
	
	}

	// get file names from params
	const char *src = argv[1];
	const char *dst = argv[2];

	int fsize = len(src);

	//create dst file for following cpy job in 2 process
	int fdw = -1;
	if( (fdw=open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0664)) == -1 )
	{
		perror("open error");
		return -1;

	}
	close(fdw);


	//define pid 
	pid_t pidr = -1;


	//create a sub process
	pidr = fork();


	if(pidr > 0)
	{
		//parent process
		cpy(src, dst, 0, fsize/2);
	}
	else if(pidr == 0)
	{
		//sub process
		cpy(src, dst, fsize/2 , fsize - (fsize/2));

		//exit with flush buffer
		exit(EXIT_SUCCESS);	

		// exit without flush buffer 
		//_exit(EXIT_SUCCESS);		
	}
	else
	{
		perror("fork error");
		return -1;
	}

	wait(NULL); // recycle process resources
		
	return 0;
}

运行结果:


6.使用多线程完成两个文件的拷贝

代码:


//  使用多线程完成两个文件的拷贝

#include <myhead.h>

typedef struct Param
{
	const char *src;
	const char *dst;
	int start;
	int size;

} param_t, *ptr_param_t;



int get_file_size(const char *src)
{
	int fdr = -1;

	if( (fdr=open(src, O_RDONLY)) == -1   )
	{
		perror("open error");
		return -1;
	}

	int fsize = lseek(fdr, 0, SEEK_END);

	return fsize;
}

int cpy(const char *src, const char *dst, int start, int size)
{
	//printf("1---\n");
	int fdr = -1;
	int fdw = -1;

	if( (fdr=open(src, O_RDONLY)) == -1   )
	{
		perror("open error");
		return -1;
	}

	if( (fdw=open(dst, O_WRONLY)) == -1   )
	{
		perror("open error");
		return -1;
	}
	
	int len = get_file_size(src);

	char buf[128] = "";

	lseek(fdr, start, SEEK_SET);
	lseek(fdw, start, SEEK_SET);


	while(len > 0)
	{
		//printf("2---\n");
		int res = read(fdr, buf, sizeof(buf) );
		//printf("start=%d, len=%d, buf=%s\n", start, len, buf);
		write(fdw, buf, res);

		len -= sizeof(buf);	
	
	}



	pthread_exit(NULL);

	return 0;

}

void *task_copy(void *arg)
{
	//resolve params
	
	ptr_param_t ptrparam = (ptr_param_t)arg; // convert void * to struct Param *
	//printf("src=%s, dst=%s, start=%d, size=%d\n", ptrparam->src, ptrparam->dst, ptrparam->start, ptrparam->size );
	cpy(ptrparam->src, ptrparam->dst, ptrparam->start, ptrparam->size );
	
}

int main(int argc, const char *argv[])
{
	if(argc != 3)
	{
		perror("input error\n");
		return -1;
	}

	const char *src = argv[1];
	const char *dst = argv[2];

	int fsize =get_file_size(src);
	printf("fsize=%d\n", fsize);


	//create dst file
	int fdw = -1;
	
	if( (fdw=open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0664)) == -1   )
	{
		perror("open error");
		return -1;
	}

	param_t param1 = {src, dst, 0, fsize/2};
	param_t param2 = {src, dst, fsize/2 , fsize - (fsize/2)};
	ptr_param_t pparam1 = &param1;
	ptr_param_t pparam2 = &param2;



	pthread_t tid = -1;

	//create a thread
	
	if(  (tid = pthread_create(&tid, NULL, task_copy, (void *)pparam1 ) ) != 0  )
	{
		return -1;
	
	}

	task_copy((void *)pparam2 );



	pthread_join(tid, NULL);


	return 0;
}

运行结果运行结果


7.将互斥锁的案例

代码:

// 互斥锁的案例

#include <myhead.h>

// public resources

int money = 5000;


//1.define mutex

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;




void *task(void *task)
{
		
	
	while(1)
	{
		// 3.lock  critical resource 
	
		pthread_mutex_lock(&mutex);

		money -= 50;
		printf("lisi withdraw 50yuan, money=%d\n", money);
		
		// 4.unlock critical resource
		pthread_mutex_unlock(&mutex);


		sleep(1);
	
	}

	pthread_exit(NULL);

}


int main(int argc, const char *argv[])
{

	pthread_t tid = -1;

	// 2.init mutex
	pthread_mutex_init(&mutex, NULL);

	if( (tid=pthread_create(&tid, NULL, task, NULL))==-1   )
	{
		perror("pthread_create error");
		return -1;
	
	}

	while(1)
	{

		// 3.lock  critical resource 
	
		pthread_mutex_lock(&mutex);
		money -= 100;
		printf("zhangsan withdraw 100yuan. money=%d\n", money);

		// 4.unlock critical resource
		pthread_mutex_unlock(&mutex);

		sleep(1);
	
	}


	pthread_join(tid, NULL);
	
	// 5. destroy mutex
	pthread_mutex_destroy(&mutex);

	
	return 0;
}

运行结果


8.无名信号量实现生产者消费者程序

代码:

//   无名信号量实现生产者消费者程序

#include <myhead.h>

// 1. define a sem
sem_t sem; 

void *task_c(void *arg)
{

	while(1)
	{
		sleep(1);
		// wait for available value,  >0: value dec and continue, =0: waiting 
		sem_wait(&sem);
		printf("I consumed a car\n");
	}


	pthread_exit(NULL);

}


void *task_p(void *arg)
{

	while(1)
	{
		sleep(2);
		printf("I produced a car\n");
		// after production, sem value inc 
		sem_post(&sem);
	}


	pthread_exit(NULL);

}



int main(int argc, const char *argv[])
{

	pthread_t tid_c = -1;
	pthread_t tid_p = -1;


	// 2. init sem
	sem_init(&sem , 0, 0);
	//param 2 value 0 means thread; non 0 means process(has to be in relative processes)
	//param 3 value 0 means value


	if( pthread_create(&tid_c, NULL, task_c, NULL) != 0   )
	{

		printf("thread create error!\n");
		return -1;
	
	}


	if( pthread_create(&tid_p, NULL, task_p, NULL) != 0   )
	{

		printf("thread create error!\n");
		return -1;
	
	}


	pthread_join(tid_c, NULL);
	pthread_join(tid_p, NULL);

	// 5. destroy sem
	sem_destroy(&sem);
	
	return 0;
}

运行结果


9.条件变量实现生产者消费者程序

代码:

// 将条件变量实现生产者消费者程序

#include <myhead.h>

// 1.1 define a cond var

pthread_cond_t cond;

// 1.2 define a mutex
pthread_mutex_t mutex; 


void *task_c(void *arg)
{
	int n = 2;
	while(n--)
	{
		// 3.1 lock critical resource --> cond FIFO
		pthread_mutex_lock(&mutex);

		//3.2  critiacl code waiting in cond quere
		//inside cond, will unlock mutex -> put this into queue -> lock again
		pthread_cond_wait(&cond, &mutex);

		//3.3 unlock 
		pthread_mutex_unlock(&mutex);

		printf("I consumed a car\n");



		sleep(1);

	}


	pthread_exit(NULL);

}


void *task_p(void *arg)
{
	int n = 10;
	while(n--)
	{
		printf("I produced a car\n");
		// 4. after production, release a signal to consumer
		pthread_cond_signal(&cond);

		sleep(1);

	}
	printf("production closed!\n");

	pthread_exit(NULL);

}



#include <myhead.h>

int main(int argc, const char *argv[])
{
	int n=2;

	pthread_t tid_p = -1;
	pthread_t tid_arr[n];
	for(int i=0; i<5; i++)
	{
		tid_arr[i] = -1;

	}

	// 2.1init cond
	pthread_cond_init(&cond, NULL);

	// 2.2 init mutex 
	pthread_mutex_init(&mutex, NULL);



	if(pthread_create(&tid_p, NULL, task_p, NULL ) !=0 )
	{
		printf("thread p create error\n");
		return -1;
	}

	for (int i=0; i<5; i++)
	{
		if(pthread_create(&tid_arr[i], NULL, task_c, NULL ) !=0 )
		{
			printf("thread [%d] create error\n", i);
			return -1;
		}
	}


	for(int i=0; i<5; i++)
	{
		pthread_join(tid_arr[i] , NULL );

	}

	// 5.1
	pthread_cond_destroy(&cond); 

	//5.2
	pthread_mutex_destroy(&mutex);

	return 0;
}

运行结果

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

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

相关文章

Redis核心知识点总结

1.Redis介绍 Redis 是 NoSQL&#xff0c;但是可处理 1 秒 10w 的并发&#xff08;数据都在内存中&#xff09; 使用 java 对 redis 进行操作类似 jdbc 接口标准对 mysql&#xff0c;有各类实现他的实现类&#xff0c;我们常用的是 druid 其中对 redis&#xff0c;我们通常用 J…

链表面试题的总结和思路分享

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

Vite4、Vue3、Axios 针对请求模块化封装搭配自动化导入(简单易用)

针对请求模块化封装搭配自动化导入&#xff08;简单易用&#xff09; 目标目录目标代码前提步入正题src / utils / index.jssrc /api / index.jssrc /api / request.jssrc /api / service.jssrc /api / utils.jssrc /api / modules / demo.js 自动化配置vite.config.jseslint 校…

《PySpark大数据分析实战》-01.关于数据

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

VSCode安装与使用

VS Code 安装及使用 1、下载 进入VS Code官网&#xff1a;地址&#xff0c;点击 DownLoad for Windows下载windows版本 注&#xff1a; Stable&#xff1a;稳定版Insiders&#xff1a;内测版 2、安装 双击安装包&#xff0c;选择我同意此协议&#xff0c;再点击下一步 选择你…

jquery实现省市区三级联动

一、技术: 前端采用的是jsp页面 后端采用springmvc+mybatis+mysql8 效果图 二、cascadeSelect.jsp页面 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%String path = request.getContextPath();String basePath = r…

流程画布开发技术方案归档(G6)

&#x1f3a8; 在理想的最美好世界中&#xff0c;一切都是为最美好的目的而设。 —— 伏尔泰 如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; 一、技术选型 •从可维护性和可拓展性出发 •基本满足 1&#xff1a;链接: https://github.com/hukaibaihu/vue-org…

Java 手写设计HashMap源码,让面试官膜拜

Java 手写HashMap源码&#xff0c;让面试官膜拜 一&#xff0c;手写源码 这是一个模仿HashMap的put&#xff0c;get功能的自定义的MyHashMap package cn.wxs.demo;import java.io.Serializable; import java.util.*; import java.util.function.BiConsumer;class MyHashMap&…

【解密考研英语:Python数据分析与可视化】

解密考研英语&#xff1a;Python数据分析与可视化 背景数据集技术选型功能实现创新点 大家好&#xff0c;欢迎阅读我的CSDN博客&#xff01;今天我将分享一项有关考研英语真题的数据分析与可视化项目&#xff0c;希望对考研学子提供更有针对性的复习帮助。 背景 作为考研学子…

【TwinCAT学习笔记 1】TwinCAT开发环境搭建

写在前面 作为技术开发人员&#xff0c;开启任何一项开发工作之前&#xff0c;首先都要搭建好开发环境&#xff0c;所谓磨刀不误砍材工&#xff0c;一定要有耐心&#xff0c;一次不行卸载再装。我曾遇到过一个学生&#xff0c;仅搭建环境就用了两周&#xff0c;这个过程也是一…

Docker容器的可视化管理工具—DockerUI本地部署与远程访问

文章目录 前言1. 安装部署DockerUI2. 安装cpolar内网穿透3. 配置DockerUI公网访问地址4. 公网远程访问DockerUI5. 固定DockerUI公网地址 前言 DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基…

3接上篇 我的自定义GPTs的改进优化 与物理世界连接成功 GPTs的创建与使用定义和执行特定任务的功能模块 通过API与外部系统或服务的交互

https://blog.csdn.net/chenhao0568/article/details/134875067?spm1001.2014.3001.5502 从服务器日志里看到请求多了一个“location” 23.102.140.123 - - [08/Dec/2023:14:02:20 0800] "GET /getWeather.php?location&locationNewYork HTTP/1.1" 200 337 &…

公式识别任务各个链条全部打通

目录 引言公式识别任务是什么&#xff1f;公式识别任务解决方案初探使用建议写在最后 引言 随着LaTeX-OCR模型转换问题的解决&#xff0c;公式识别任务中各个链条已经全部打通。小伙伴们可以放开膀子干了。 解决业界问题的方案&#xff0c;并不是单独训练一个模型就完事了&am…

Spring Bean基础

写在最前面: 本文运行的示例在我github项目中的spring-bean模块&#xff0c;源码位置: spring-bean 前言 为什么要先掌握 Spring Bean 的基础知识&#xff1f; 我们知道 Spring 框架提供的一个最重要也是最核心的能力就是管理 Bean 实例。以下是其原因&#xff1a; 核心组件…

data_loader返回的每个batch的数据大小是怎么计算得到的?

data_loader是一个通用的术语&#xff0c;用于表示数据加载器或数据批次生成器。它是在机器学习和深度学习中常用的一个概念。 一、data loader 数据加载器&#xff08;data loader&#xff09;是一个用于加载和处理数据集的工具&#xff0c;它可以将数据集划分为小批次&#…

Oracle 中换行chr(10)、回车chr(13)

一、前言 chr(n)&#xff1a;返回 ascii 值对应的字符。 ascii(char)&#xff1a;返回字符 char对应的ascii 值。 chr(n) 和 ascii(char) 作用刚好是相反的。 SQL> select chr(65) from dual; 控制台显示&#xff1a;ASQL> select ascii(A) from dual; 控制台显示&am…

Oracle高可用一家老小全在这里

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

FL Studio2024永久免费体验版下载

FL Studio中文绿色21版是一款无需要安装的汉化版本&#xff0c;它是一款非常专业的音频编辑软件&#xff0c;可以让你的音乐突破想象力的限制哦&#xff0c;FL Studio21中文版可以制作出不同音律的节奏&#xff0c;FL Studio内置众多电子合成音色&#xff0c;只Styrus可以让人激…

鸿蒙开发组件之ForEach列表

一、ForEach函数 ForEach函数是一个迭代函数&#xff0c;需要传递两个必须参数和一个可选参数。主要通过迭代来获取参数arr中的数据不断的生成单个Item来生成鸿蒙中的列表样式 二、先创建单个的Item的UI 通过嵌套Row与Column来实现单个Item的UI。例如图中没有折扣的可以看成一…

C++-引用和指针区别

文章目录 1.变量的组成2.指针2.1 定义2.2 使用指针操作变量2.3 为什么使用指针 3.引用3.1 定义3.2 引用注意事项 4.引用和指针的区别 1.变量的组成 变量的组成&#xff1a;变量地址&#xff0c;变量名&#xff0c;变量值 例&#xff1a; int i 12;2.指针 2.1 定义 指针用于存…