进阶指针(三)--- qsort函数(快速排序)的使用和(用冒泡排序)模拟实现

图片来源于网络

✨博客主页:小钱编程成长记
🎈博客专栏:进阶C语言
🎈推荐相关博文:进阶C语言(一)、进阶C语言(二)

进阶指针(三)

  • 8.回调函数(下)
    • 8.2 qsort函数的使用
      • 8.2.1 介绍:
      • 8.2.1 用qsort函数排序整型数组
      • 8.2.3 用qsort函数排序结构体数组
    • 8.3 用冒泡排序模拟实现qsort函数的快速排序
      • 8.3.1 回顾冒泡排序
      • 8.3.2 开始模拟
      • 8.3.3 代码展示
      • 8.3.4 用新的冒泡排序函数排序整型数组
      • 8.3.5 用新的冒泡排序函数排序结构体数组
  • 总结

8.回调函数(下)

我们接着上次的回调函数开始讲解剩下的qsort部分,如果没看过的话,大家可以先看看进阶C语言(二)

8.2 qsort函数的使用

8.2.1 介绍:

回调函数的案例:qsort

  • qsort是一个库函数,头文件是stdlib.h,声明头文件后可直接使用。
  • qsort是底层使用的快速排序的方式,是对数据进行排序的。
  • qsort可以用来排序任意类型的数据。

我们可以在网站cplusplus中查询这个函数的使用方法。
来自网络截图

qsort函数,有四个参数:
void qsort(void* base,//待排序数组的第一个元素的地址,并将其转化为void*型size_t num,//待排序数组的元素的个数size_t size,//待排序数组的一个元素的大小(单位字节)int (*compar)(const void* e1, const void* e2)//函数指针---compar指向了一个函数,这个函数是用来比较两个元素的; //e1,e2中存放的是需要比较的两个元素的的地址);
compar函数:
//举例: 
比较函数--提供整型数据的比较方法 
int compar(const void* e1, const void* e2)  
{ 		return *(int*)e1 - *(int*)e2;//升序排序, 	
//当结果>0(e1指向的元素位于e2之后)时,返回一个>0的数; 	 	 
//当结果==0(e1指向的元素和e2指向的元素相同),返回0;
//当结果<0(e1指向的元素位于e2之前)时,返回一个<0的数; 
}
注意重点:

1.排序整型数组,两个元素可以直接用>比较
2.排序结构体数组,两个结构体的数据可能不能直接使用>比较,
》也就是说,不同类型的数据,比较大小的方式有差异。

  • void* 是无具体类型的指针类型
  • void* 类型的指针可以存放各种类型数据的地址
  • void* 类型的指针不能解引用,也不能进行 ± 整数的操作(因为是无类型,不知道要跳过几个字节)

void* 类型的指针不能解引用,我们可以先强转为其它类型再进行±操作。
qsort并不知道它要排序的数组中元素的类型,并且不同类型数据的比较方式不同。
所以在使用qsort之前,要先给它提供要比较的类型数据的比较方法。

8.2.1 用qsort函数排序整型数组

用qsort函数排序整型数组#include <stdio.h>
#include <stdlib.h>//比较函数--提供整型数据的比较方法
int int_compar(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;//升序排序,//当结果>0(e1指向的元素位于e2之后)时,返回一个>0的数;//当结果==0(e1指向的元素等于e2指向的元素)时,返回0;//当结果<0(e1指向的元素位于e2之前)时,返回一个<0的数;
}//打印函数
void print(int arr[], size_t sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}int main()
{int arr[] = { 0,9,8,7,6,5,4,3,2,1 };size_t sz = sizeof(arr) / sizeof(arr[0]);print(arr, sz);//快速排序qsort(arr, sz, sizeof(arr[0]), int_compar);print(arr, sz);return 0;
}

8.2.3 用qsort函数排序结构体数组

#include <stdio.h>
#include <stdlib.h>
#include <string.h>//结构体
struct Stu
{char name[20];int age;
};按年龄排序
打印函数
//void print_test1(struct Stu *s1, size_t sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%s %d ", s1[i].name, s1[i].age);
//	}
//	printf("\n");
//}
//
比较函数
//int compare_age(const void* e1, const void* e2)
//{
//	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
//}
//
//void test1()
//{
//	struct Stu s1[] = { {"zhangsan", 20},{"lisi", 12},{"wangwu", 30} };
//	size_t sz = sizeof(s1) / sizeof(s1[0]);
//
//	print_test1(s1, sz);//排序前
//	qsort(s1, sz, sizeof(s1[0]), compare_age);
//	print_test1(s1, sz);
//}//按名字字母ASCII从小到大排序
//打印函数
void print_test2(struct Stu* s2, size_t sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%s %d ", s2[i].name, s2[i].age);}printf("\n");
}//比较函数
int compare_name(const void* e1, const void* e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}void test2()
{struct Stu s2[] = { {"zhangsan", 20},{"lisi", 12},{"wangwu", 30} };size_t sz = sizeof(s2) / sizeof(s2[0]);print_test2(s2, sz);//排序前qsort(s2, sz, sizeof(s2[0]), compare_name);print_test2(s2, sz);
}int main()
{//test1();test2();return 0;
}

8.3 用冒泡排序模拟实现qsort函数的快速排序

目标: 包含回调函数,使用冒泡排序的算法,模拟实现一个排序函数(qsort),可以排序任意类型的数据。

8.3.1 回顾冒泡排序

冒泡排序的思想: 两两相邻的元素进行比较

在这里插入图片描述
在这里插入图片描述

//冒泡排序
#include <stdio.h>//冒泡排序函数
void bubble_sort(int arr[], size_t sz)
{int i = 0;//冒泡排序的趟数for (i = 0; i < sz-1; i++){int j = 0;//每趟要比较的对数for (j = 0; j < sz - 1 - i; j++){//判断是否要交换if (arr[j] > arr[j + 1]){//交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}		}}
}//打印函数
void print_arr(int arr[], size_t sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}void test()
{int arr[] = { 9,8,7,6,5,4,3,2,1,0 };//降序size_t sz = sizeof(arr) / sizeof(arr[0]);print_arr(arr, sz);//排序前//升序排列bubble_sort(arr, sz);print_arr(arr, sz);//排序后
}int main()
{test();return 0;
}

8.3.2 开始模拟

通过上面对冒泡排序的回顾,我们得到冒泡排序函数的基本框架:

//冒泡排序函数
void bubble_sort(int arr[], size_t sz)
{int i = 0;//冒泡排序的趟数for (i = 0; i < sz-1; i++){int j = 0;//每趟要比较的对数for (j = 0; j < sz - 1 - i; j++){//判断是否要交换if (arr[j] > arr[j + 1]){//交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}		}}
}
qsort函数:

在这里插入图片描述

如何模拟:

  1. 首先要给冒泡排序函数传递数组的首元素地址,
    因为我们要模仿qsort排序任意类型的数据,所以形参要能接收任意类型的地址。
    上篇文章讲了void* 类型的指针可以接收任意类型的地址,所以参数我们可以这样写bubble_sort(void *base)

  2. 想要给任意一个数组排序,都要先知道数组有几个元素,
    因为计算数组 / 元素大小的操作数sizeof的返回值是size_t类型的,
    所以参数可以写成bubble_sort(void *base, size_t num)

  3. 有了首元素地址和数组元素个数还不够,还不能知道每个元素的地址。
    站在冒泡排序函数的角度并不知道传来的是什么类型的地址,所以不能通过指针+1的方式找到下一个元素的地址,
    在这里插入图片描述
    但是我们可以将要排序数组每个元素的大小(字节)传过来,知道了一个元素有几个字节,指针跳过这几个字节就指向了下一个元素。 所以参数可以写成bubble_sort(void *base, size_t num, size_t size)

  4. 进阶指针(三)中讲过,不同类型的数据比较大小的方式可能不同, 所以要排序数据的程序员需要先给冒泡排序函数 传 数据的比较函数,冒泡排序函数用函数指针接收,所以参数可以写成 bubble_sort(void *base, size_t num, size_t size, int compar(const void *e1, const void *e2))

  5. 比较函数:
    int compar(const void *e1, const void *e2)
    因为要排序多种类型的数据,所以要用void*类型的指针接收。
    e1是一个指针,存放一个要比较元素的地址
    e2是一个指针,存放一个要比较元素的地址
    e1指向的元素 > e2指向的元素,返回 > 0的整型数字
    e1指向的元素 == e2指向的元素,返回整型数字0
    e1指向的元素 < e2指向的元素,返回 < 0的整型数字
    这也是比较函数返回类型是int的原因。

  6. 在冒泡排序函数中要调用比较函数,来判断两个元素是否需要交换,返回值>0交换。
    比较函数中的参数应该填要比较元素,那就要先找到元素的地址。
    站在冒泡排序函数的角度并不知道传来的是什么类型的地址,所以不能通过指针+1的方式找到下一个元素的地址。
    已知首元素的地址,元素的个数num,一个元素占size字节,我们可以将首元素的地址强转成char*型的,指针向后移size个字节就指向了下一个元素,(一个size个字节大小的元素的地址,在数值上==这个元素所占的第一个字节的地址)
    (char *) base + size * 1 就是下标为1的元素的地址,
    (char *)base + size * j 是下标为 j 的元素的地址,
    (char *)base + size * (j+1) 是下标为 j+1 的元素的地址。
    在这里插入图片描述

//冒泡排序函数
void bubble_sort(const void *base, size_t num, size_t size, int compar(const void *e1, const void *e2))
{int i = 0;//冒泡排序的趟数for (i = 0; i < num-1; i++){int j = 0;//每趟要比较的对数for (j = 0; j < num - 1 - i; j++){//判断是否要交换if ((compar((char*)base + size*j, (char*)base + size*(j+)) > 0){//交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}		}}
}
  1. 如果两个元素需要交换,因为站在冒泡排序函数的角度不知道有排序数组的类型,所以不能直接用 * 解地址将元素整个交换。(*访问的范围是类型的大小)。
    我们知道一个元素有size个字节,所以可以一个字节一个字节的交换,先创建一个字节的空间用来过渡,通过这个空间来交换。
    在这里插入图片描述
//注意:函数不能嵌套定义
//交换函数
void swap(char *buf1, char *buf2)
{char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;
} //判断是否要交换
if ((compar((char*)base + size*j, (char*)base + size*(j+)) > 0)
{//交换swap((char*)base + size*j, (char*)base + size*(j+1))
}		

8.3.3 代码展示

//交换函数
void swap(char *buf1, char *buf2)
{char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;
} //冒泡排序函数---泛型编程-什么类型都支持的编程
void bubble_sort(const void *base, size_t num, size_t size, int compar(const void *e1, const void *e2))
{int i = 0;//冒泡排序的趟数for (i = 0; i < num-1; i++){int j = 0;//每趟要比较的对数for (j = 0; j < num - 1 - i; j++){//判断是否要交换if ((compar((char*)base + size*j, (char*)base + size*(j+)) > 0)//此时,compar指向的函数就是回调函数{//交换swap((char*)base + size*j, (char*)base + size*(j+1))}		}}
}

8.3.4 用新的冒泡排序函数排序整型数组

#include <stdio.h>通用冒泡函数
//交换函数
void swap(char* buf1, char* buf2, size_t size)
{int i = 0;for (i = 0; i < size; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}//泛型编程---什么类型都支持的编程
void bubble_sort(const void* base, size_t num, size_t size, int compar(const void* e1, const void* e2))
{int i = 0;//冒泡排序的趟数for (i = 0; i < num - 1; i++){//一趟冒泡排序int j = 0;for (j = 0; j < num - 1 - i; j++){//通过比较判断两个元素是否需要交换if (compar((char*)base + size * j, (char*)base + size * (j + 1)) > 0){//交换swap((char*)base + size * j, (char*)base + size * (j + 1), size);}}}
}//打印函数
void print_test1(int* arr, size_t sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}//比较函数
int compare_int(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}//主要程序
void test1()
{int arr[] = { 0,9,8,7,6,5,4,3,2,1 };size_t sz = sizeof(arr) / sizeof(arr[0]);print_test1(arr, sz);bubble_sort(arr, sz, sizeof(arr[0]), compare_int);print_test1(arr, sz);
}int main()
{test1();return 0;
}

8.3.5 用新的冒泡排序函数排序结构体数组

注意:
  • ->的优先级比 强制转换操作符 高。
  • strcmp用来比较字符串,头文件是string.h
  • 函数在使用之前要先声明,函数的定义也是一种特殊的声明
#include <stdio.h>
#include <string.h>通用冒泡函数
//交换函数
void swap(char* buf1, char* buf2, size_t size)
{int i = 0;for (i = 0; i < size; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}//泛型编程---什么类型都支持的编程
void bubble_sort(const void* base, size_t num, size_t size, int compar(const void* e1, const void* e2))
{int i = 0;//冒泡排序的趟数for (i = 0; i < num-1; i++){//一趟冒泡排序int j = 0;for(j=0; j<num-1-i; j++){//通过比较判断两个元素是否需要交换if (compar((char*)base + size * j, (char*)base + size * (j + 1)) > 0){//交换swap((char*)base + size * j, (char*)base + size * (j + 1), size);}}}
}//结构体
struct Stu
{char name[20];int age;
};按年龄比较
比较函数——给排序函数提供要排序的数据的比较方法。函数在使用之前要先声明,函数的定义也是一种特殊的声明
//int compar_age(const void* e1, const void* e2)
//{
//	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
//}
//
//
//
打印函数
//void print_test1(struct Stu* S1, size_t sz)
//{
//	int i = 0;
//	for (i = 0; i < sz; i++)
//	{
//		printf("%s %d  ", S1[i].name, S1[i].age);
//	}
//	printf("\n");
//}
//
//
主要程序
//void test1()
//{
//	struct Stu S1[] = { {"zhangsan", 20},{"lisi", 12},{"wangwu", 30} };
//	size_t sz = sizeof(S1) / sizeof(S1[0]);
//
//	print_test1(S1, sz);//排序前
//
//	bubble_sort(S1, sz, sizeof(S1[0]), compare_age);//按年龄排序
//	print_test1(S1, sz);//排序后
//}//按名字的字母大小(ASCII)从小到大排序//打印函数
void print_test2(struct Stu* S2, size_t sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%s %d ", S2[i].name, S2[i].age);}printf("\n");
}//比较函数
int compare_name(const void *e1, const void *e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);//->的优先级比 强制转换操作符 高。strcmp用来比较字符串,头文件是string.h
}//主要程序
void test2()
{struct Stu S2[] = { {"zhangsan", 20},{"lisi", 12},{"wangwu", 30} };size_t sz = sizeof(S2) / sizeof(S2[0]);print_test2(S2, sz);//排序前bubble_sort(S2, sz, sizeof(S2[0]), compare_name);//按名字排序print_test2(S2, sz);
}int main()
{//test1();test2();
}

总结

本篇文章我们学习了qsort函数,如何用冒泡排序模拟qsort函数实现能够排序任意类型的数据。最后,感谢大家的阅读!大家一起进步!

点赞收藏加关注,C语言学习不迷路!
图片来源于网络

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

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

相关文章

ThreeJS-3D教学四-光源

three模拟的真实3D环境&#xff0c;一个非常炫酷的功能便是对光源的操控&#xff0c;之前教学一中已经简单的描述了多种光源&#xff0c;这次咱们就详细的讲下一些最常见的光源&#xff1a; AmbientLight 该灯光在全局范围内平等地照亮场景中的所有对象。 该灯光不能用于投射阴…

Windows系统利用cpolar内网穿透搭建Zblog博客网站并实现公网访问内网!

文章目录 1. 前言2. Z-blog网站搭建2.1 XAMPP环境设置2.2 Z-blog安装2.3 Z-blog网页测试2.4 Cpolar安装和注册 3. 本地网页发布3.1. Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1. 前言 想要成为一个合格的技术宅或程序员&#xff0c;自己搭建网站制作网页是绕…

ElementUI之首页导航+左侧菜单->mockjs,总线

mockjs总线 1.mockjs 什么是Mock.js 前后端分离开发开发过程当中&#xff0c;经常会遇到以下几个尴尬的场景&#xff1a; - 老大&#xff0c;接口文档还没输出&#xff0c;我的好多活干不下去啊&#xff01; - 后端小哥&#xff0c;接口写好了没&#xff0c;我要测试啊&#x…

【前端】ECMAScript6从入门到进阶

【前端】ECMAScript6从入门到进阶 1.ES6简介及环境搭建 1.1.ECMAScript 6简介 &#xff08;1&#xff09;ECMAScript 6是什么 ECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff…

【sgTileImage】自定义组件:瓦片图拖拽局部加载、实现以鼠标为中心缩放

特性&#xff1a; 支持缩放瓦片图&#xff0c;定义瓦片图初始缩放比例&#xff0c;以鼠标所在位置为中心缩放支持局部拖拽加载 sgTileImage源码 <template><div :class"$options.name"><div class"sg-ctrl"><label>缩放百分比&l…

ElasticSearch映射与模板介绍

一、前言 前面有相关系列文章介绍了ES的基本概念和各种版本SDK的使用&#xff0c;ES现在已升级到8.5版本&#xff0c;有些概念和SDK用法都有很大变化&#xff0c;后续ES相关的文章会以8.3版本为基准介绍一些实际中应用需要掌握的概念以及一些比较实际的例子。 二、映射 ES环…

Flask配合Echarts写一个动态可视化大屏

ch 技术 后端&#xff1a;flask 可视化&#xff1a;echarts 前端&#xff1a;HTMLJavaScriptcss 大屏布局 大屏拆分 案例项目中大屏可按版块进行拆解&#xff0c;会发现这里大屏主要由标题、折线图、柱状图、地图、滚动图和词云等组成&#xff0c;整体可切分为8个版块&…

Unity 制作登录功能02-创建和链接数据库(SQlite)

国际惯例&#xff1a;先看效果 1.SQlite是一种嵌入型数据库 在Unity开发游戏时使用SQLite有多种原因&#xff0c;以下是其中一些主要原因&#xff1a; 嵌入式数据库&#xff1a;SQLite是一个嵌入式数据库引擎&#xff0c;这意味着它不需要单独的服务器进程。这使得使用SQLite非…

VUE2项目:尚品汇VUE-CLI脚手架初始化项目以及路由组件分析(一)

标题 环境VUE2目录publicassetscomponentsmain.jsbabel.config.jspackage.jsonvue.config.js 项目路由分析Header与Footer非路由组件完成Header示例 路由组件的搭建声明式导航编程式导航 Footer组件的显示与隐藏路由传递参数重写push和replace三级联动组件拆分附件 环境 前提要…

子序列问题集合

子序列问题 删除一次得到的最大和最大子数组和最长公共子序列&#xff1a;最长上升子序列&#xff08;要输出序列&#xff0c;和最大长度&#xff09;1.dp2.贪心二分 导弹拦截 &#xff08;最长上升/下降子序列长度&#xff09; 删除一次得到的最大和 class Solution { public:…

Elasticsearch基础篇(二):Elasticsearch在windows和liunx上的安装部署

Elasticsearch简介 前言1. Windows环境部署Elasticsearch1.1 下载并解压Elasticsearch压缩包1.2 命令行启动elasticsearch1.3 验证是否成功启动elasticsearch1.4 关闭Elasticsearch1.5 在Windows上安装Elasticsearch作为服务 2. Liunx环境部署Elasticsearch安装 Elasticsearch …

Android Studio 的android.jar文件在哪儿

一般在&#xff1a;C:\Users\admin\AppData\Local\Android\Sdk\platforms\android-33下&#xff08;不一定是33&#xff0c;这个得看你Android Studio->app->builde.gradle的targetSdk是多少&#xff09; 怎么找&#xff1a; 1.打开Android Studio 粘贴地址后&#xff0…

UE学习记录07----C++中使用事件委托

1.c定义多播委托&#xff0c;示例代码&#xff1a; #include "Delegates/Delegate.h"DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyDelegate, UObject*, SelectAgent);/****/ UCLASS(Blueprintable, DisplayName "VM_PlaceEntity") class PR_PLACEE…

在nodejs中如何防止ssrf攻击

在nodejs中如何防止ssrf攻击 什么是ssrf攻击 ssrf&#xff08;server-side request forgery&#xff09;是服务器端请求伪造&#xff0c;指攻击者能够从易受攻击的Web应用程序发送精心设计的请求的对其他网站进行攻击。(利用一个可发起网络请求的服务当作跳板来攻击其他服务)…

word 多级目录的问题

一、多级标题自动编号 --> 制表符 -> 空格 网址&#xff1a; 【Word技巧】2 标题自动编号——将多级列表链接到样式 - YouTube 二、多级列表 --> 正规形式编号 网址&#xff1a;Word 教学 - 定框架&#xff1a;文档格式与多级标题&#xff01; - YouTube 三、目…

【项目】基于C++11实现的数据库连接池

文章目录 前置知识关键技术点项目背景连接池功能点介绍MySQL Server参数介绍功能设计连接池功能点介绍开发平台选型 关于MySQL数据库编程MySQL接口介绍 测试表设计Connection设计数据库配置文件mysql.conf日志文件log.hppConnectionPool设计压力测试源码链接&#xff1a; 前置知…

南京大学【软件分析】13 Static Analysis for Security

文章目录 1. Information Flow Security2. Confidentiality and Integrity3. Explicit Flows and Covert/Hidden Channels4. Taint Analysis污点分析案例 1. Information Flow Security 引起安全问题最主要的两大原因是&#xff1a;injection errors&#xff08;2013-2019排名…

【深度学习实验】卷积神经网络(六):卷积神经网络模型(VGG)训练、评价

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 构建数据集&#xff08;CIFAR10Dataset&#xff09; a. read_csv_labels&#xff08;&#xff09; b. CIFAR10Dataset 2. 构建模型&#xff08;FeedForward&…

【网络协议】TCP

TCP协议全称为传输控制协议(Transmission Control Protocol).要理解TCP就要从他的特性开始说&#xff0c;这些特性各自之间或多或少各有联结&#xff0c;需要以宏观视角来看待。 目录&#xff1a; 1.TCP报文格式 因为报文解释过于繁琐&#xff0c;具体内容请看这篇文章TCP报文…

问题 - 谷歌浏览器 network 看不到接口请求解决方案

谷歌浏览器 -> 设置 -> 重置设置 -> 将设置还原为其默认值 查看接口情况&#xff0c;选择 All 或 Fetch/XHR&#xff0c;勾选 Has blocked cookies 即可 如果万一还不行&#xff0c;卸载浏览器重装。 参考&#xff1a;https://www.cnblogs.com/tully/p/16479528.html