0
点赞
收藏
分享

微信扫一扫

一、c++学习(功能菜单)


1.0 课程目标(画饼)

我们的课程目标是做一个联机版的贪吃蛇,实现这个贪吃蛇的功能也跟课程分了3个部分。

第一部分:c++,主要实现单机版贪吃蛇,还有选项(我们玩贪吃蛇都有没墙模式,和墙模式),说明(其实就是个显示)

第二部分:linux系统编程,主要实现继续游戏(游戏玩到一半我退出,然后重来进来,可以继续游戏),登录(网络时代了,肯定需要联网),聊天(实现一个简单的IM)。(这一部分还没准备,不知道是不是画饼,哈哈哈)

第三部分:数据库,不能再想之前一样使用文件存储了,大数据时代,还是需要数据库,虽然我们数据不大。这一部分主要实现好友,(也是简单的IM),还有最高分,(游戏没有排行榜,是没有灵魂的,参考羊了个羊),日志模块,(这个没有在页面中体现,但是作为成熟的后端,如果有bug肯定需要查问题的)

好了课程目标,画饼到此结束,我们进入正题。

接下来我们第一部c++正式开始。

1.1 熟悉c++

我们先用vs2022来创建一个c++的工程,这个工程已经附带了一个hello world输出信息。

我们学习一门语言,都是比较喜欢使用hello world。

我们来看一下c++有什么不一样

// zero.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>   // 头文件不一样了,c语言的头文件是#include <stdio.h>
// 注意c语言的头文件是有.h的,c++是没有.h后缀,当然如果自己写的头文件,加上.h后缀也是可以的

int main()    // main函数还是一样的配方
{
    std::cout << "Hello World!\n";   // c++的输出方式和c的输出不一样,
    // c的风格是:printf("Hello World\n"); 
    // 虽然在c++中我们一样也可以使用c,但是我们要做好入乡随俗的准备。
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单   //  运行程序的快捷键,也可以直接点击按钮
// 调试程序: F5 或调试 >“开始调试”菜单

1.0.0 命名空间

我们在输出语句中看到了std::cout 这个std是何方神圣。

其实std就是c++的一个命名空间,这个命名空间名字叫std,只不过这个std有点特殊,c++很多标准库函数都在这个命名空间中,包括了cout输出,cin输入,另外还有很多很多。std是standard 的缩写,意思是“标准命名空间”。

c++为啥定义一个命名空间?

我们之前在写c语言的时候,如果是多人开发一个项目,每一个人写一个.c文件,怕函数名会冲突,所以一般不需要暴露在外面的函数名前面都加一个static,表示这个函数作用域是在该文件内。

c++当然可以继续用static,毕竟c++是c的超集,但是c++有自己的解决方案,就是命名空间,我们来举个栗子:

// zero.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

/*
    1.0.0 命名空间代码
*/

namespace jiangyou
{
    void peixun()
    {
        std::cout << "酱油师兄培训c++" << std::endl;
    }
}

namespace yangshijie
{
    void peixun()
    {
        std::cout << "杨师姐培训前端js" << std::endl;
    }
}

// 如果按道理来说,这两个函数的名字是一样的,所以会编译不过
// 但是因为我们加了命名空间,所以并不冲突,这里编译一下看看

// 如果我们觉得不想写那么多命名空间的名字,我们可以直接引入这个命名空间
using namespace yangshijie;
// 那如果我继续引入jiangyou的命名空间,两个函数就会二义性
// using namespace jiangyou;  // 这样这个函数就会报错

// 最后一个,可以直接引入这个命名空间的函数,而不用引入整个命名空间
using yangshijie::peixun;

int main()
{
    /*
        1.0 代码
         std::cout << "Hello World!\n";
    */
    
    /* 1.0.0 命名空间代码 */
    // 那我们添加了命名空间,那怎么调用呢?
    // peixun();  // 如果直接调用是报错的
    //jiangyou::peixun();  // 我们需要把命名空间带上,这样调用
    //yangshijie::peixun(); 

    peixun();   // 如果我们引入了命名空间,直接调用这个函数,就是相当是这个函数的命名空间中的函数。
}

1.2 功能菜单

我们这次培训,不会一股脑讲语法,因为市面上讲语法的视频很多,比如:王建伟老师的c++视频就不错,需要的话,百度一下就知道了。好了废话不多说,我们来看看我们这一节课的需求,

菜单栏有下面菜单
(1)  继续
(2)  新游戏
(3)  游戏选项(级别/游戏类型)
(4)  游戏规则说明
(5)  最高分
(6)  商店
(7)  好友

我们这节课的任务就是写出一个简单的功能菜单。

写个菜单嘛,那不是很简单,我们一样都输出就可以了。

// 1.1功能菜单.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

using namespace std;   // 觉得写这个玩意比较累

int main()
{
    cout << "继续" << endl;		// 当然我们也可以使用printf来实现,不过既然是写c++了,就尽量少用printf
    cout << "新游戏" << endl;
    cout << "游戏选项" << endl;
    cout << "游戏规则说明" << endl;
    cout << "最高分" << endl;
    cout << "商店" << endl;
    cout << "好友" << endl;
}

这个不是简简单单么,哈哈哈哈。

这样就结束了么,我们第一节课讲的真快,哈哈哈。

1.3 按键输入

虽然我们在上一节中把功能菜单实现了出来,但我们菜单最重要的是交互,而不是显示,显示出来我们操作不了,也没啥用。

在c语言中,我们一般都是使用scanf或者getchar等接受键盘数据,c++的话,有自己封装的>>。

char ch;		// char 是一个类型
cin >> ch;		// 这个时候c++ 的输入,后面的可以接受任意变量,这里我就不尝试了
// c语言的输入有scanf这个函数,我们可以忘记了
cout << ch;

float ff;
cin >> ff;		
cout << ff;

1.4 变量

变量在程序中,是比较重要的,我们不同的变量长度,会对应这不同的大小,比如我们上面用cin接受输入的值的时候,有字符,有小数,有整数,我们代码也是有区分。

下面我们就来看看c++的一下变量与大小:

// one.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <climits>
using namespace std;


int main()
{
	cout << "最大值:" << endl;
	cout << "int类型:" << INT_MAX << " int字节:" << sizeof(int) << endl;
	cout << "char类型:" << CHAR_MAX << " char字节:" << sizeof(char) <<  endl;
	cout << "short类型:" << SHRT_MAX << " short字节:" << sizeof(short) << endl;
	cout << "long类型:" << LONG_MAX << " long字节:" << sizeof(long) <<  endl;
	cout << "long long类型:" << LLONG_MAX << " long long字节:" << sizeof(long long) << endl;
	cout << "signed char类型:" << SCHAR_MAX << " signed char字节:" << sizeof(signed char) << endl;
	cout << "unsigned char类型:" << UCHAR_MAX << " unsigned char字节:" << sizeof(unsigned char)  << endl;
	cout << "unsigned short类型:" << USHRT_MAX << " unsigned short字节:" << sizeof(unsigned short)  << endl;
	cout << "unsigned int类型:" << UINT_MAX << " unsigned int字节:" << sizeof(unsigned int)  << endl;
	cout << "unsigned long类型:" << ULONG_MAX << " unsigned long字节:" << sizeof(unsigned long) <<  endl;
	cout << "unsigned long long类型:" << ULLONG_MAX << " unsigned long long字节:" << sizeof(unsigned long long) <<  endl;
	cout << endl << endl << "最小值:" << endl;
	cout << "char类型:" << CHAR_MIN << " char字节:" << sizeof(char) <<  endl;
	cout << "short类型:" << SHRT_MIN << " short字节:" << sizeof(short) << endl;
	cout << "int类型:" << INT_MIN << " int字节:" << sizeof(int) << endl;
	cout << "long类型:" << LONG_MIN << " long字节:" << sizeof(long) << endl;
	cout << "long long类型:" << LLONG_MIN << " long long字节:" << sizeof(long long) << endl;

	cout << endl << endl << "浮点数:" << endl;
	cout << "float类型:"  << " float字节:" << sizeof(float) << endl;
	cout << "double类型:" << " double字节:" << sizeof(double) << endl;
	cout << "long double类型:"  << " long double字节:" << sizeof(long double) << endl;

	cout << "wchar_t类型:" << " wchar_t字节:" << sizeof(wchar_t) << endl;
	cout << "char8_t类型:" << " char8_t字节:" << sizeof(char8_t) << endl;




	cout << "min(bool)          : " << numeric_limits<bool>::min() << endl;
	cout << "min(int)           : " << numeric_limits<int>::min() << endl;
	cout << "min(unsigned int)  : " << numeric_limits<unsigned int>::min() << endl;
	cout << "min(short int)     : " << numeric_limits<short int>::min() << endl;
	cout << "min(long int)      : " << numeric_limits<long int>::min() << endl;
	cout << "min(float)         : " << numeric_limits<float>::min() << endl;
	cout << "min(double)        : " << numeric_limits<double>::min() << endl;
	cout << "min(long double)   : " << numeric_limits<long double>::min() << endl;

	cout << "max(bool)          : " << numeric_limits<bool>::max() << endl;
	cout << "max(int)           : " << numeric_limits<int>::max() << endl;
	cout << "max(unsigned int)  : " << numeric_limits<unsigned int>::max() << endl;
	cout << "max(short int)     : " << numeric_limits<short int>::max() << endl;
	cout << "max(long int)      : " << numeric_limits<long int>::max() << endl;
	cout << "max(float)         : " << numeric_limits<float>::max() << endl;
	cout << "max(double)        : " << numeric_limits<double>::max() << endl;
	cout << "max(long double)   : " << numeric_limits<long double>::max() << endl;
}

1.5 常量

如果有变量,那就有常量,常量表示该值不可修改,比如PI的值,这个就是我们计算圆面积的一个常量。再说,就我们目前的小黑框显示页面,如果我们想定义一个高640,宽320的一个界面(这个界面我们下节课会介绍怎么写),因为我们一个程序这个长宽的页面是固定的,所以我们这里可以用常量表示。

const int Height = 640;
const int Width = 320;   // 定义常量的关键字就是const

在c++中,就对const做了严格的约束,会把const int a=10;存储到一个符号表中,键值是a,值是10,这样通过a就能找到10。

如果int *p = &a; 这时候,c++会临时申请一个变量,并且把地址返回给p,这样操作之后,常量a是没有被改变的。

1.5.1 c语言的常量

在c语言中,其实我们是可以修改常量的,比如:const int a = 10;这个变量a虽然是常量,但是编译器并没有严格约束,如果用指针操作a的地址还是可以修改的。(这个可以自行测试)

1.5.2 const的局限

虽然const可以定义常量,但是有一个很大的缺陷,就是不能在编译时期使用,比如,就是不能做数组的长度。

const int len = 5;
int a[len];  // 这样是编译失败的

那如果这样子,我们怎么解决?如果是c语言的话,这里我们就会使用到宏定义:

#define LEN 5
int a[LEN];

这样子编译是通过的,总感觉这样比较low,哈哈哈。所以c++11引入了一个新的关键字constepr。

1.5.3 constexpr引入

constexpr这个也是常量的意思,我们也可以直接拿来定义常量。

constexpr int len = 5;
int a[len];

这样编译是没问题的,其实这个关键字还可以修饰函数,这个函数会在编译时期,会调用这个函数,并计算出返回值,如果有返回值的话。

constexpr int Getlen()
{
	return 5;
}

int a2[Getlen()];

这样是可以编译通过的,如果我们在constexpr中使用了运行时变量,这个是肯定编译不过的。

static int dd = 10;

constexpr int Getlen1()
{
	return dd;
}

int a2[Getlen1()];   // 直接编译失败

关于这个还有一个高级玩法,模板元编程(这些是c++高级玩法,目前就不要学习先)

constexpr unsigned long long Fibonacci2(unsigned long long n)
{
	return n >= 2 ? Fibonacci2(n - 1) + Fibonacci2(n - 2) : n;
}

在编译时期,就可以把这个递归问题给计算出来,之后的脑洞有多大,就看大家的想象了。

关于这个其他用法,大家可以自行学习。

1.6 运算符

大家都是老司机了,这个运算符就不说了。

1.7 auto & decltype

我们开始上硬菜了。

总感觉是c++怕别人说自己的变量类型不能推导,是静态语法,而py,js,php这些是动态语言,他们那些动态语言,就是变量可以随时拿来用,都不用定义变量类型,由编译器推断,如果学了js就会明白,代码量一大,确实比较懵逼,所以后来出现了一个ts。

好了,话又说回到c++,c++为了紧跟时代潮流,c++11引入了两个自动推导类型的关键字,而且c++为了追求性能,推导过程肯定是放在编译阶段的。

我们来简单使用一下:

auto x = 10;   // x -> int
auto f = 1.1f;  // f -> float

decltype(x) xx;  // xx -> int
decltype(f) ff;
decltype(1.4) d;

虽然现在举的例子,是比较简单,那时候因为我们目前学习的都是比较简单的数据类型,以后我们学习到类模板的时候,就会明天写这个auto的用处了。

目前我们就先介绍到这里,以后会更加说明的。

1.8 基本语句

这个基本语句,if while for,就不说了吧,老司机了大家。

c++11不甘寂寞,引入了一个范围for,可能看到其他语言都是这种写法吧,c++11也就引进了。

// 1.8 范围for
	// c++11 在原来的for循环的基础上加了一个范围for,范围for也是有限制的,其实要是一个序列,
	// 1.数组
	int att[10] = { 1,2,3,4,5 };
	for (auto a : att)
	{
		cout << a << endl;
	}

	// 但是new出来的数组不行
	//int* patt = new int[10];
	//for (auto a : patt)		// 不行
	//{
	//	cout << a << endl;
	//}

	// 2.还是就是我们后面学习的string
	string sss = "I Love Wuxeu\n";
	for (auto c : sss)
	{
		cout << c << endl;
	}

	// 3.还有后面学习的容器,这个我先写,后面学习到了就知道了。
	vector<int> v = { 1,2,3,4 };
	for (auto vv : v)
	{
		cout << vv << endl;
	}

1.9 数组

大家都会数组没有?数组也比较简单,就是类型相同的一个顺序集合。

// 1.9 数组
	int att2[10] = { 1,2,3,4,5 };			// 这个就是数组,类型都是int
	// 数组位置存储是顺序的,可以打印出来看看
	for (int i = 0; i < 10; i++)
	{
		printf("i = %d %p\n", i, &att2[i]);			// 是不是地址连续
	}

1.9.1 下标 & 指针 那个更快?

// 因为数组的地址是连续的,我们才能使用下标获取
	int tu = att2[4];		// 可以这么取数据

	// 想不想看编译器对这句话是怎么转换的?

/*	// 因为数组的地址是连续的,我们才能使用下标获取
	int tu = att2[4];		// 可以这么取数据
	00007FF6C62274CE B8 04 00 00 00       mov         eax, 4
	00007FF6C62274D3 48 6B C0 04          imul        rax, rax, 4		// rax存的就是int的大小,rax*4 就是att2的偏移
	00007FF6C62274D7 8B 84 05 68 03 00 00 mov         eax, dword ptr att2[rax]
	00007FF6C62274DE 89 85 C4 03 00 00    mov         dword ptr[tu], eax
*/

// 这时候我想到,当初老师说用指针操作数组,效率更高,那我们来试试?
	int* ptu = att2;
	int tu2 = *(ptu + 8);

	/* int* ptu = att2;
	00007FF6F4FBBD24 48 8D 85 68 03 00 00 lea         rax, [att2]
	00007FF6F4FBBD2B 48 89 85 E8 03 00 00 mov         qword ptr[ptu], rax
		int tu2 = *(ptu + 4);
	00007FF6F4FBBD32 48 8B 85 E8 03 00 00 mov         rax, qword ptr[ptu]
	00007FF6F4FBBD39 8B 40 10             mov         eax, dword ptr[rax + 10h]		// 10h=16 然后编译器直接帮我们算好了
	00007FF6F4FBBD3C 89 85 04 04 00 00    mov         dword ptr[tu2], eax
	*/

	// 结论,老师没有骗我们,哈哈哈哈

1.9.2 练手1:提取图像的色调

本来数组写到这里就结束了,后面突然有一个需求,需要提取图像色调,也刚好符合数组练手的要求,就加上来一起讲了。

1.9.3 练手2:图像中占比TOP N的颜色

如果只是提出最大值,那是很简单的,我们提高一下需求难度,提取TOP 10种颜色。

这个不知道放这里合适不合适,反正这题是面试高频题,面试题是,在一篇文章中,取出使用最多的10个字母。

1.10 字符串

我们在生活中随时可见的都是字符串,比如名字,地址,甚至电话号码都是用字符串存储的。在我们游戏中,使用字符串的地方更多,玩家的名字,还有我们要写的菜单栏,也是需要字符串的。我们现在就学习字符串,然后立马就可以使用到我们的菜单栏上了。

1.10.1 C类型字符串

我们先复习一下c语言的字符串。

c语言的字符串定义有两种:

  1. char * (字符指针)
  2. char [] (字符数组)

这两种我们来试试:

// 这竟然要加const少见
    const char* str = "I Love wuxie";

    char str2[] = "I Love wuxie2";
    cout << str << " " << str2 << endl;

    // 第一种 字符指针的方式,我们不能修改字符串的内容,这是因为char *指向的字符串,存储到只读区(这个我们分析内存分布的时候才讲)
    //str[1] = 'd';
    // 第二种 字符数组,是可以修改内容的,因为这个是存储在我们栈里面的
    str2[2] = 'd';

    cout << str2 << endl;

    // 这里是不是有疑问了,只有一个指针,怎么知道这个字符串的长度呢?
    // c类型的字符串会在结尾的地方有一个字符'0'  ,这个0不是数字0,是字符0
    // 所以字符串的长度都是遍历到结尾才知道的
    char* pStr3 = str2;
    while (*pStr3)
    {
        cout << *pStr3 << " ";
        pStr3++;  // 指针不知道的我们等下分析
    }
    cout << endl << "结束了";

也正因为c语言的字符串需要最后的\0来做结尾,导致很多新手程序员经常忘记这个,所以c++才做了升级。

关于c语言的字符串处理这个链接讲的很仔细:

C语言超全面讲解字符串函数

1.10.2 string

c++作为c语言的进化版,引入了string类,类是什么,我们之后再说,我们先来看看string怎么使用。

string s1 = "I Love China";

string s2(s1);
string s3("哈哈哈");

cout << s1 << s2 << s3 << endl;

是不是很简单,并且不用操作长度问题,string类可以简单理解为,里面有一个字符数组,还有一个长度,就是这两个值来维护这我们字符串的存储。

可以看看这个string的常见函数

String的常见函数

不过使用最多的,就是string拼接,string拼接是怎么直接相加的,很方便,并且还有一个转换成c的字符串函数:s1.c_str() 这样就能转成c类型的字符串了

1.10.3 wchar_t与wstring

其实在c++98标准中,除了char表示一个字节的字符外,还定义了宽字符wchar_t。

wchar_t d = '中';   // 支持的

这个类型是支持中文的,不过wchar_t的宽度是由编译器决定的,windows上,多数是16位,而在linux上就会被实现为32位。

这样导致跨平台不兼容,后面c++标准会引进其他的字符串类型。

不过除了wchat_t之后,c++11其实也支持wstring,这是一个宽字符串:

wstring wgg = L"中国人";
wcout.imbue(std::locale("chs"));
wcout << wgg << " " << wgg.size() << endl;   // 这个也需要专门wcout 来输出,很少见到有使用

不过前面需要加L前缀,感觉比较少用吧,我们这里就知道一下把。

1.10.4 c++11对字符串扩展

  1. char16_t:用于存储UTF-16编码的Unicode数据
  2. char32_t:用于存储UTF-32编码的Unicode数据
  3. chat8_t:c++20用于存储UTF-8编码的Unicode数据

由于这几个类型,所以添加了几个前缀:

  1. u8表示为UTF-8编码
  2. u表示为UTF-16编码
  3. U表示为UTF-32编码

// c++11对字符串的扩展
	char16_t c16 = u8'a';

	cout << "c16: " << sizeof(c16) << endl;		// 用的比较少

除了对字符扩展之外,还对字符串也做了扩展

Strings library

std::string std::basic_string

std::wstring std::basic_string<wchar_t>

std::u8string (since C++20) std::basic_string<char8_t>

std::u16string (since C++11) std::basic_string<char16_t>

std::u32string (since C++11)std::basic_string<char32_t>

// c++11对字符串的扩展
	char16_t c16 = u8'a';

	cout << "c16: " << sizeof(c16) << endl;		// 用的比较少

	std::u16string u16 = u"中国人不骗中国人";
	cout.widen(2);
	// cout << "u16: " << u16 << endl;    // 这个好像也输出不了   具体就不研究了,目前来看用的地方不多

1.10.5 c++17字符串视图

在c++17中,引入了一个字符串视图:std::string_view。它可以让我们向处理字符串一样处理字符序列,而不需要为它分配空间。

这样看着是不是很完美,其实不是的,std::string_view只是引用一个外部字符串序列,也就是一个指向真正字符串的指针。

一、c++学习(功能菜单)_学习

借用了网络上的图,还不错,就是这个意思,总感觉怪怪的。

string_view hello{ "hello world" };

cout << hello << endl;

// 并且也定义这些
/*using u8string_view = basic_string_view<char8_t>;
	using u16string_view = basic_string_view<char16_t>;
	using u32string_view = basic_string_view<char32_t>;
	using wstring_view = basic_string_view<wchar_t>;*/

这个我们记住一下,需要用的时候再用。用的时候注意这个string_view指向的string对象不能释放,这就是由自己控制的了。

string* sstr = new string("hello world");

	string_view hello = *sstr;
	cout << hello << endl;
	delete sstr;
	cout << hello << endl;

	// 演示不能更改
	string* sstr2 = new string("hello world");
	string_view hello2 = *sstr2;
	// hello2[2] = '3';		// 字符串视图不能修改,只能缩写视图,或者读取元素

错误示范,用这个一定要注意指向的问题。

视图可以用做函数参数,接受的实参类型,比较多:

void show(string_view view)
{
	cout << "view: " << view << endl;
}	

// 视图可以用作函数参数,后面写了之后发现,不管用什么参数,都可以接受,视图牛逼
string* sstr2 = new string("hello world");
string_view hello2 = *sstr2;

show(hello2);
show(*sstr2);

string s = "hahah";
show(s);

const char* pss = "你好";
show(pss);

char str3[] = "I Love wuxie2";
show(str3);

1.11 菜单栏实现

// 01.4  菜单栏实现.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<conio.h>

using namespace std;

constexpr int MENUS_MAX = 9;    // 定义9个菜单

// 我们知道了有字符串数组,我们这词就存储起来
string menus[MENUS_MAX] = { "继  续" , "新游戏" , "选  项" , "说  明", "最高分", "好  友", "聊  天", "商  店", "登  录" };

enum class Page : char {
	Welcome = 0, // 欢迎页面
	Menus,		 // 菜单页面
	Continue,	 // 继续游戏页面
	New,		 // 新游戏页面
	Selected,	 // 选项页面
	Explain,	// 说明页面
	Score,		// 分数页面
	Friend,		// 好友页面
	Chat,		// 聊天页面
	Shop,		// 商店页面
	Login,		// 登录页面
};


int main()
{
	//std::cout << "Hello World!\n";

	char ch;
	int index = 0;

	Page page = Page::Menus;

	while (1)
	{
		system("cls");				// 这个是系统的小黑框 清屏函数

		// 这里可以使用for来替换
		/*cout << "继续" << endl;
		cout << "新游戏" << endl;
		cout << "游戏选项" << endl;
		cout << "游戏规则说明" << endl;
		cout << "最高分" << endl;
		cout << "商店" << endl;
		cout << "好友" << endl;*/
		//cout << index << endl;

		// 我们需要在菜单栏前面+* 表示我选中了这个
		string prex = "  ";

		for (int i = 0; i < MENUS_MAX; i++)
		{
			if (i == index)
			{
				prex = " *";
			}
			else
			{
				prex = "  ";
			}

			string show = prex + menus[i];    // 我们可以直接用+号拼接

			cout << show << i << index << endl;
		}

		// 这里为啥不用cin,是因为cin需要回车,这个函数是conio.h的函数,不需要使用回车就可以获取到按键的值
		ch = _getch();

		switch (ch)
		{
		case 'H':
			if (index > 0)
			{
				index--;
			}


			break;

		case 'P':
			if (index < MENUS_MAX - 1)
			{
				index++;
			}
			break;
		}


	}

}

1.12 作业

面试题 17.14. 最小K个数

https://leetcode.cn/problems/smallest-k-lcci/


举报

相关推荐

0 条评论