【C语言步行梯】C语言实现三子棋游戏(含详细分析)

news2024/11/18 0:36:30

在这里插入图片描述

🎯每日努力一点点,技术进步看得见
🏠专栏介绍:【C语言步行梯】专栏用于介绍C语言相关内容,每篇文章将通过图片+代码片段+网络相关题目的方式编写,欢迎订阅~~

文章目录

  • 需求分析
  • 具体实现
    • 主函数体
    • 菜单实现
    • 游戏实现
      • 棋盘初始化
      • 显示棋盘
      • 玩家下棋
      • 电脑下棋
      • 判断棋盘是否已满
      • 判断输赢
      • 游戏函数主体
    • 完整代码
    • 分文件编写


需求分析

上课摸鱼的时候,我们可以画个九宫格,在里面画上圆圈,或者叉。现在,我们通过C语言实现这个三子棋游戏,实现用户与电脑下棋。
在这里插入图片描述

具体实现

主函数体

在主函数体内,我们需要调用一个menu函数,用它提醒用户:输入1开始游戏,输入0退出游戏。接收用户输入后,通过switch语句,执行game()函数或者退出游戏。menu和game函数将在下文中讲解。

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择>");
		scanf("%d", &input);
		switch(input)
		{
			case 1:
				game();//游戏具体实现函数
				break;
			case 0:
				printf("游戏结束\n");
				break;
			default:
				printf("输入有误,请重新输入\n");
		}
	}while(input);
	return 0;
}

菜单实现

首先,我们需要一个菜单,提示用户:输入1可以开始游戏,输入0会退出游戏。我通过封装一个menu函数实现↓↓↓

void menu()
{
	printf("*********************************************\n");
	printf("************** 1.play  0.exit ***************\n");
	printf("*********************************************\n");
}

游戏实现

棋盘初始化

我们通过一个char board[3][3]来存储棋盘。如果board[i][j]为空格,表示该位置还没有下棋;如果board[i][j]存储’*‘(星号),表示该位置用户已经下棋;如果board[i][j]存储‘#’(井号),表示该位置电脑已经下棋。
在这里插入图片描述
但在开始游戏前,我们需要将棋盘数组每个元素都初始化空格。↓↓↓

void initBoard(char board[ROW][COL], int rows, int cols)
{
	for(int i = 0; i < rows; i++)
	{
		for(int j = 0; j < cols; j++)
		{
			board[i][j] = ' ';
		}
	}
}

显示棋盘

在游戏过程中,玩家或者电脑下完棋后,需要显示棋盘。用户才能知道当前棋盘的落子情况。

void displayBoard(char board[ROW][COL], int rows, int cols)
{
	for(int i = 0; i < rows; i++)
	{
		for(int j = 0; j < cols; j++)
		{
			printf(" %c ", board[i][j]);
			if(j != cols - 1)
				printf("|");
			else
				printf("\n");
		}
		if(i != rows - 1)
		{
			for(int j = 0; j < cols; j++)
			{
				printf("---");
				if(j != cols - 1)
					printf("|");
				else
					printf("\n");
			}
		}
	}
}

上方打印棋盘效果如下图所示。
在这里插入图片描述

玩家下棋

提示玩家输入下棋的坐标,接收到坐标后,我们需要判断该坐标是否为空格(表示还没有棋子),如果是空格,则下棋成功;如果不是空格,则下棋失败。

void playerAddChess(char board[ROW][COL], int rows, int cols)
{
	printf("玩家下棋\n");
	displayBoard(board, rows, cols);
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入下棋坐标>");
		scanf("%d %d", &x, &y);
		if (x > rows || x <= 0 || y > cols || y <= 0)
		{
			printf("该坐标超出棋盘边界,请重新输入\n");
			continue;
		}
		if (board[x - 1][y - 1] != ' ')
		{
			printf("该坐标已经下过棋子,请重新输入\n");
			continue;
		}
		board[x - 1][y - 1] = '*';
		break;
	}
	
}

电脑下棋

通过随机数函数生成x,y坐标。如果生成的坐标位置为空格,则电脑下棋完成;如果该坐标已被占用,则重新生成坐标。

void computerAddChess(char board[ROW][COL], int rows, int cols)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while(1)
	{
		x = rand() % 3 + 1;
		y = rand() % 3 + 1;
		if(board[x][y] != ' ')
			continue;
		else
		{
			board[x - 1][y - 1] = '#';
			break;
		}
	}
	displayBoard(board, rows, cols);
}

判断棋盘是否已满

假设经过判断,没有三个棋子能连成一条直线,那就无法判断谁赢谁输。若在此时,棋盘已经满了,但还是没有三个棋子练成一条直线,则双方平手(平局)。如下图所示。
在这里插入图片描述
因此,我们需要一个函数,用来判断棋盘是否已经满了。如果满了,则游戏结束;没有满则游戏继续。

int isFull(char board[ROW][COL], int rows, int cols)
{
	for(int i = 0; i < rows; i++)
	{
		for(int j = 0; j < cols; j++)
		{
			if(board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

判断输赢

在电脑或者玩家下完棋后,我们需要判断当前状态下,是否有人获胜。根据三子棋的规则,三个棋子连成直线即获胜。下面函数中,如果玩家获胜,则返回’*‘(星号);如果电脑获胜,则返回’#‘(井号);如果棋盘满了,则返回Q,表示平局;如果没人获胜,棋盘也没满,则游戏继续,返回’C’。

char isWin(char board[ROW][COL], int rows, int cols)
{
	//对每一行判断
	for(int i = 0; i < rows; i++)
	{
		if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
			return board[i][0];
	}
	//对每一列判断
	for(int i = 0; i < cols; i++)
	{
		if(board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
			return board[0][i];
	}
	//对角线
	if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		return board[0][0];
	if(board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
		return board[0][2];
	
	if(isFull(board, rows, cols))
		return 'Q';
	return 'C';
}

游戏函数主体

在实现了上述各个函数后,我们只要稍加组织,就可以实现游戏了。

void game()
{
	char board[ROW][COL] = { 0 };
	initBoard(board, ROW, COL);
	char ret = 0;
	while (1)
	{
		playerAddChess(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
			break;
		computerAddChess(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	switch (ret)
	{
	case '*':
		printf("玩家获胜\n");
		break;
	case '#':
		printf("电脑获胜\n");
		break;
	case 'Q':
		printf("平局\n");
		break;
	}
}

完整代码

上面代码中主函数中没有加入随机数种子,在下面代码中加入了srand((unsigned int)time(NULL)),同时对于上面出现ROW、COL的宏定义等也在下方代码整体给出。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 3
#define COL 3

void menu()
{
	printf("*********************************************\n");
	printf("************** 1.play  0.exit ***************\n");
	printf("*********************************************\n");
}

void initBoard(char board[ROW][COL], int rows, int cols)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void displayBoard(char board[ROW][COL], int rows, int cols)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			printf(" %c ", board[i][j]);
			if (j != cols - 1)
				printf("|");
			else
				printf("\n");
		}
		if (i != rows - 1)
		{
			for (int j = 0; j < cols; j++)
			{
				printf("---");
				if (j != cols - 1)
					printf("|");
				else
					printf("\n");
			}
		}
	}
}

void playerAddChess(char board[ROW][COL], int rows, int cols)
{
	printf("玩家下棋\n");
	displayBoard(board, rows, cols);
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入下棋坐标>");
		scanf("%d %d", &x, &y);
		if (x > rows || x <= 0 || y > cols || y <= 0)
		{
			printf("该坐标超出棋盘边界,请重新输入\n");
			continue;
		}
		if (board[x - 1][y - 1] != ' ')
		{
			printf("该坐标已经下过棋子,请重新输入\n");
			continue;
		}
		board[x - 1][y - 1] = '*';
		break;
	}
	
}

void computerAddChess(char board[ROW][COL], int rows, int cols)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % 3 + 1;
		y = rand() % 3 + 1;
		if (board[x - 1][y - 1] != ' ')
			continue;
		else
		{
			board[x - 1][y - 1] = '#';
			break;
		}
	}
	displayBoard(board, rows, cols);
}

int isFull(char board[ROW][COL], int rows, int cols)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

char isWin(char board[ROW][COL], int rows, int cols)
{
	//对每一行判断
	for (int i = 0; i < rows; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
			return board[i][0];
	}
	//对每一列判断
	for (int i = 0; i < cols; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
			return board[0][i];
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		return board[0][0];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
		return board[0][2];

	if (isFull(board, rows, cols))
		return 'Q';
	return 'C';
}

void game()
{
	char board[ROW][COL] = { 0 };
	initBoard(board, ROW, COL);
	char ret = 0;
	while (1)
	{
		playerAddChess(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
			break;
		computerAddChess(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	switch (ret)
	{
	case '*':
		printf("玩家获胜\n");
		break;
	case '#':
		printf("电脑获胜\n");
		break;
	case 'Q':
		printf("平局\n");
		break;
	}
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//游戏具体实现函数
			break;
		case 0:
			printf("游戏结束\n");
			break;
		default:
			printf("输入有误,请重新输入\n");
		}
	} while (input);
	return 0;
}

分文件编写

可以创建game.h保存头文件,及各函数的函数声明;game.c保存各个函数的具体实现;main.c中保存主函数。

game.h ↓↓↓

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 3
#define COL 3

//初始化棋盘
void initBoard(char board[ROW][COL], int rows, int cols);

//菜单
void menu();

//打印棋盘
void displayBoard(char board[ROW][COL], int rows, int cols);

//玩家下棋
void playerAddChess(char board[ROW][COL], int rows, int cols);

//电脑下棋
void computerAddChess(char board[ROW][COL], int rows, int cols);

//游戏
void game();

//判断棋盘是否已经满了
int isFull(char board[ROW][COL], int rows, int cols);

//判断是否赢
char isWin(char board[ROW][COL], int rows, int cols);

game.c ↓↓↓

#include "game.h"

void menu()
{
	printf("*********************************************\n");
	printf("************** 1.play  0.exit ***************\n");
	printf("*********************************************\n");
}

void initBoard(char board[ROW][COL], int rows, int cols)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void displayBoard(char board[ROW][COL], int rows, int cols)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			printf(" %c ", board[i][j]);
			if (j != cols - 1)
				printf("|");
			else
				printf("\n");
		}
		if (i != rows - 1)
		{
			for (int j = 0; j < cols; j++)
			{
				printf("---");
				if (j != cols - 1)
					printf("|");
				else
					printf("\n");
			}
		}
	}
}

void playerAddChess(char board[ROW][COL], int rows, int cols)
{
	printf("玩家下棋\n");
	displayBoard(board, rows, cols);
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入下棋坐标>");
		scanf("%d %d", &x, &y);
		if (x > rows || x <= 0 || y > cols || y <= 0)
		{
			printf("该坐标超出棋盘边界,请重新输入\n");
			continue;
		}
		if (board[x - 1][y - 1] != ' ')
		{
			printf("该坐标已经下过棋子,请重新输入\n");
			continue;
		}
		board[x - 1][y - 1] = '*';
		break;
	}
	
}

void computerAddChess(char board[ROW][COL], int rows, int cols)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % 3 + 1;
		y = rand() % 3 + 1;
		if (board[x - 1][y - 1] != ' ')
			continue;
		else
		{
			board[x - 1][y - 1] = '#';
			break;
		}
	}
	displayBoard(board, rows, cols);
}

int isFull(char board[ROW][COL], int rows, int cols)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

char isWin(char board[ROW][COL], int rows, int cols)
{
	//对每一行判断
	for (int i = 0; i < rows; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
			return board[i][0];
	}
	//对每一列判断
	for (int i = 0; i < cols; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
			return board[0][i];
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
		return board[0][0];
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
		return board[0][2];

	if (isFull(board, rows, cols))
		return 'Q';
	return 'C';
}

void game()
{
	char board[ROW][COL] = { 0 };
	initBoard(board, ROW, COL);
	char ret = 0;
	while (1)
	{
		playerAddChess(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
			break;
		computerAddChess(board, ROW, COL);
		ret = isWin(board, ROW, COL);
		if (ret != 'C')
			break;
	}
	switch (ret)
	{
	case '*':
		printf("玩家获胜\n");
		break;
	case '#':
		printf("电脑获胜\n");
		break;
	case 'Q':
		printf("平局\n");
		break;
	}
}

main.c ↓↓↓

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//游戏具体实现函数
			break;
		case 0:
			printf("游戏结束\n");
			break;
		default:
			printf("输入有误,请重新输入\n");
		}
	} while (input);
	return 0;
}

🚩这篇文章结束了~~
如果文章中出现了错误,欢迎私信或留言。(๑•̀ㅂ•́)و✧
有任何疑问请评论或私信哦~~o( ̄▽ ̄)ブ

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

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

相关文章

LLM之RAG实战(三十)| 探索RAG语义分块策略

在LLM之RAG实战&#xff08;二十九&#xff09;| 探索RAG PDF解析解析文档后&#xff0c;我们可以获得结构化或半结构化的数据。现在的主要任务是将它们分解成更小的块来提取详细的特征&#xff0c;然后嵌入这些特征来表示它们的语义&#xff0c;其在RAG中的位置如图1所示&…

【GitHub】使用git链接下载很慢?试试服务器配置SSH,起飞

参考文献 保姆级教学&#xff0c;教你用配置SSH拉取github代码 CentOS ssh -T gitgithub.comgit config --global user.name "learnore" git config --global user.email "15200831505163.com"cd /root/.ssh vim id_rsa.pubGitHub Settings 结果 下载速…

力扣L13--- 409.最长回文串(JAVA版)-2024年3月1日

1.题目描述 2.知识点 注1&#xff1a;向下取整是将一个数值向下舍入到最接近的整数&#xff0c;但不超过这个数值的整数。具体规则如下&#xff1a; 对于正数&#xff0c;向下取整后得到的整数是不大于原数值的最大整数&#xff1b; 对于负数&#xff0c;向下取整后得到的整数…

uniapp——第2篇:编写vue语法

前提&#xff0c;建议先学会前端几大基础&#xff1a;HTML、CSS、JS、Ajax&#xff0c;还有一定要会Vue!&#xff08;Vue2\Vue3&#xff09;都要会&#xff01;&#xff01;&#xff01;不然不好懂 一、去哪写&#xff1f; 就在【pages】的你的人一个页面文件夹里的【.vue】文…

简单的网页制作

1网页编写格式 <!DOCTYPE html> <html><head><meta charset"utf-8"> <title>中文测试。。。。</title></head><body>这里是测试body测试内容。。。</body> </html>2标签 在body内<h1></h1&…

突破编程_前端_JS编程实例(工具栏组件)

1 开发目标 工具栏组件旨在模拟常见的桌面软件工具栏&#xff0c;所以比较适用于 electron 的开发&#xff0c;该组件包含工具栏按钮、工具栏分割条和工具栏容器三个主要角色&#xff0c;并提供一系列接口和功能&#xff0c;以满足用户在不同场景下的需求&#xff1a; 点击工具…

中间件 | RPC - [Dubbo]

INDEX 1 Dubbo 与 web 容器的关系2 注册发现流程3 服务配置3.1 注册方式 & 订阅方式3.2 服务导出3.3 配置参数 4 底层技术4.1 Dubbo 的 spi 机制4.2 Dubbo 的线程池4.3 Dubbo 的负载均衡策略4.3 Dubbo 的协议 1 Dubbo 与 web 容器的关系 dubbo 本质上是一个 RPC 框架&…

leetcode代码记录(动态规划基础题(斐波那契数列)

目录 1. 题目&#xff1a;2. 斐波那契数列&#xff1a;小结&#xff1a; 1. 题目&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a…

基于高德地图JS API实现Vue地图选点组件

基于高德地图JS API2.0实现一个搜索选择地点后返回给父组件位置信息的功能&#xff0c;同时可以进行回显 目录 1 创建key和秘钥1.1 登录高德地图开放平台1.2 创建应用1.3 绑定服务创建秘钥 2 使用组件前准备2.1 导入loader2.2 在对应的组件设置秘钥2.3 引入css样式 3 功能实现…

【C语言】整型提升与算术转换

一、表达式求值 在我们平常的表达式求值的题目中&#xff0c;虽然看似是道很简单的题目&#xff1b;但是出题人总是会埋坑&#xff0c;其中最常见的就是整型提升与算术转换。 二、整型提升 C语⾔中整型算术运算总是⾄少以缺省(默认)整型(int)类型的精度来进⾏的&#xff1b;…

【MySQL基础】MySQL基础操作二

文章目录 &#x1f34e;1.数据库约束&#x1f350;约束类型&#x1f346;1.1NOT NULL&#x1f346;1.2UNIQUE&#x1f346;1.3DEFAULT&#x1f346;1.4PRIMARY KEY&#x1f346;1.5FOREIGN KEY &#x1f34f;2.查询操作&#x1f35f;2.1聚合查询&#x1f354;2.1.1聚合函数&…

视频号电商的风口来了!这个消息还有多少人不知道?

大家好&#xff0c;我是电商糖果 短视频做电商&#xff0c;这几年的热度真的是非常高&#xff0c;就是因为热度太高了&#xff0c;才让视频号也动了电商的心思。 腾讯推出的视频号是为了和抖音对打&#xff0c;这几年靠着微信输送的流量&#xff0c;视频号的日活已经渐渐有赶…

JavaSE-----认识异常【详解】

目录 一.异常的概念与体系结构&#xff1a; 1.1异常的概念&#xff1a; 1.2一些常见的异常&#xff1a; 1.3异常的体系结构&#xff1a; 1.4异常的分类&#xff1a; 二.异常的处理机制&#xff1a; 2.1 抛出异常&#xff1a; 2.2异常的捕获&#xff1a; 2.3try-catch-&…

JavaWeb一些开发问题

一、Restful package com.example.crudtest1.pojo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data NoArgsConstructor AllArgsConstructor public class Result {private Integer code;//响应码&#xff0c;1 代表成功; 0 代表失…

浅易理解:卷积神经网络(CNN)

浅易理解卷积神经网络流程 本文的目录&#xff1a; 1 什么卷积神经网络 2 输入层 3 卷积层 4 池化层 5 全连接层 传统的多层神经网络只有 输入层、隐藏层、输出层 卷积神经网络&#xff08;CNN)&#xff1a; 在多层神经网络的基础上&#xff0c;加入了更加有效的特征学习部分…

315曝光黑灰产业链:主板机

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 315晚会曝光主板机黑灰产业链&#xff0c;主板机是什么呢?可能很多人还不知道。在这里松松给大家普及一下&#xff0c;也欢迎大家关注卢松松哟! 主板机是什么呢? 通过报废手机的主板&#xff0c;拆出来后组装成主…

【Linux进程状态】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、直接谈论Linux的进程状态 看看Linux内核源代码怎么说 1.1、R状态 -----> 进程运行的状态 1.2、S状态 -----> 休眠状态(进程在等待“资源”就绪) 1.3、T状…

NFTScan 正式上线 Blast NFTScan 浏览器和 NFT API 数据服务

2024 年 3 月 15 号&#xff0c;NFTScan 团队正式对外发布了 Blast NFTScan 浏览器&#xff0c;将为 Blast 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商&#xff0c;Blast 是继 Bitcoin、Ethereum、BNBChain、…

Linux 系统调用函数fork、vfork、clone详解

文章目录 1 fork1.1 基本介绍1.2 fork实例1.2.1多个fork返回值1.2.2 C语言 fork与输出1.2.3 fork &#x1f4a3; 2 vfork2.1 基本介绍2.2 验证vfork共享内存 3 clone3.1 基本介绍3.2 clone使用 1 fork 1.1 基本介绍 #include <sys/types.h> #include <unistd.h>p…

2024年【危险化学品经营单位主要负责人】找解析及危险化学品经营单位主要负责人模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位主要负责人找解析考前必练&#xff01;安全生产模拟考试一点通每个月更新危险化学品经营单位主要负责人模拟考试题目及答案&#xff01;多做几遍&#xff0c;其实通过危险化学品经营单位主要负责人…