贪吃蛇(一)--用C++编写一个简单的贪吃蛇

2023-11-12

这里简单介绍怎么用C++编写一个简单的黑白框的贪吃蛇游戏,复杂的加了可视化界面程序点击这里贪吃蛇(二)–easyX图形库进行可视化界面制作

首先分析在黑白框中的贪吃蛇需要哪些功能:
(1)需要能在界面指定位置(x,y)直接输出对应内容
(2)需要动态数组储存蛇的身体节点
(3)需要能接收键盘指令对贪吃蛇运动方向进行调整
(4)需要随机生成食物
(5)判断蛇是否撞到墙或者自己的身体

基本满足这些功能就可以实现一个简单的贪吃蛇,但是为了游戏的稳定性我们需要尽可能考虑详细,避免程序出bug。现在依次对这5个功能进行实现。

1.在界面指定位置(x,y)输出对应内容
这里直接引用C语言本身存在的一个操作台函数,代码如下:

#include<iostream>
#include<windows.h>
using namespace std;
//在指定位置显示内容 
void gotoxy(int x,int y,char c)
{
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo; //variablendklaration
	HANDLE hConsoleOut;
	hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
	GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
	csbiInfo.dwCursorPosition.X = x; //cursorposition X koordinate festlegen
	csbiInfo.dwCursorPosition.Y = y; //cursorposition Y koordinate festlegen
	SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); //den cursor an die festgelegte koordinate setzen
	printf("%c",c);//输出你指定的字符 
}  
int main()
{
	gotoxy(5,5,'*');//在坐标(5,5)的位置显示'*' 
	gotoxy(10,10,'#'); //在坐标(10,10)的位置显示'#'
	return 0;
} 

其中的gotoxy函数就是我们可以在指定位置输出指定字符的函数,其对应的库函数为"windows.h",上述代码运行结果为
在这里插入图片描述
于是我们趁热打铁,把贪吃蛇的围墙顺便画出来,围墙为一个矩形,而矩形的左上角和右下角端点坐标就可以确定这个矩形,于是我们只需要定义左上角和右下角坐标即可。

int X1=1,Y1=1;//活动范围的左上角坐标
int X2=60,Y2=30;//活动范围的右下角坐标
void init()//初始化函数 
{
	for(int i=X1;i<=X2;i++)
	{
		gotoxy(i,Y1,'#');
		gotoxy(i,Y2,'#');
	}
	for(int j=Y1;j<=Y2;j++)
	{
		gotoxy(X1,j,'#');
		gotoxy(X2,j,'#');
	}	
} 

在主函数中运行初始化函数init()结果为
在这里插入图片描述于是画出了一个简单的边框了。

2.动态数组储存蛇的身体节点
这里直接用stl库中的vector储存了吧,然后定义一个结构体表示蛇的身体节点,这样书写比较容易,嘿嘿,代码如下。

struct Snake
{
	int x,y;
};
vector<Snake>snake;

然后库函数部分记得添加vector

#include<iostream>
#include<windows.h>
#include<vector>
using namespace std;

这就是定义简单的蛇节点的动态数组了,然后我们初始化让开始的蛇头在活动范围的中间位置,然后在主函数中一直循环显示出来。这里我让蛇先按朝着往下的方向移动,蛇的节点很多,那么如何让蛇移动呢?其实只需要改变蛇头位置就行,然后往后的节点更新到上一个节点的坐标位置,比如先把蛇头位置更新给第二个节点,蛇头位置再更新成我们调整的位置。

但是蛇移动后原来位置输出的内容是需要清除的,这里我需要补充说一下了,可能在很多其他的贪吃蛇的写法中,为了书写方便直接用了system(“cls”)清空了整个界面内容,再把新的界面信息输出,这样没问题,但是黑白框不是专门用于可视化界面程序的,这样会让贪吃蛇程序看起来很卡顿,后期的可视化界面的贪吃蛇确实需要直接清空整个界面,但是现在的这个黑白框的程序没必要,我为了减小程序时间复杂度,考虑到贪吃蛇实际每次运动都是两个节点在变化,蛇头和蛇尾,蛇头是新输出的内容不管,蛇尾移动后原来的蛇尾就需要清空,于是我们在每次更新蛇的节点信息前,先把原来的蛇尾的位置清除,用gotoxy(x,y,’ ');空格就会显示没有,看起来就是清除的作用。
然后到这里完整的代码就是这样了:

#include<iostream>
#include<windows.h>
#include<vector>
using namespace std;
//在指定位置显示内容 
void gotoxy(int x,int y,char c)
{
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo; //variablendklaration
	HANDLE hConsoleOut;
	hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
	GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
	csbiInfo.dwCursorPosition.X = x; //cursorposition X koordinate festlegen
	csbiInfo.dwCursorPosition.Y = y; //cursorposition Y koordinate festlegen
	SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); //den cursor an die festgelegte koordinate setzen
	printf("%c",c);//输出你指定的字符 
}  
int X1=1,Y1=1;//活动范围的左上角坐标
int X2=60,Y2=30;//活动范围的右下角坐标
struct Snake
{
	int x,y;
};
vector<Snake>snake;
void init()//初始化函数 
{ 
	for(int i=X1;i<=X2;i++)
	{
		gotoxy(i,Y1,'#');
		gotoxy(i,Y2,'#');
	}
	for(int j=Y1;j<=Y2;j++)
	{
		gotoxy(X1,j,'#');
		gotoxy(X2,j,'#');
	}
	snake.clear();//初始化清空	
	Snake t;
	t.x=(X1+X2)/2;
	t.y=(Y1+Y2)/2;
	snake.push_back(t);
} 
//更新的位置,上下左右 
int XX[4]={0,0,-1,1};
int YY[4]={-1,1,0,0}; 
void Print(int direction)//显示蛇的内容
{
	int n=snake.size()-1;
	gotoxy(snake[n].x,snake[n].y,' ');//先清除蛇尾留下的痕迹 
	for(int i=n;i>=1;i--)
	snake[i]=snake[i-1];//进行节点更新
	snake[0].x+=XX[direction];
	snake[0].y+=YY[direction]; 
	for(int i=1;i<=n;i++)
	gotoxy(snake[i].x,snake[i].y,'*');
	gotoxy(snake[0].x,snake[0].y,'@');//蛇头用@表示 
} 
int main()
{
	init();
	while(true)
	{
		Print(1);
		Sleep(500);//延迟500ms,控制程序显示时间	
	} 
	return 0;
} 

动态图显示如下

在这里插入图片描述
到这里看起来就有点意思了,我们继续干。

3.接收键盘指令对贪吃蛇运动方向进行调整
现在要根据我们输入的指令进行贪吃蛇运动的调整,我们的贪吃蛇运动是通过死循环+睡眠延时所以看起来在运动一样,那么怎么在循环过程中加入操作指令呢,这里又需要用到一个函数了,叫kbhit函数,这个函数是键盘监听函数,主要功能就是如果当前你按了键盘(不论什么键),这个函数就会返回true,表示有键盘指令,不然就是false,表示当前无操作。于是我们可以利用这个输入我们的操作指令。其次还需要一个函数,getch(),这个函数是输入单个字符,不用再按回车,因为我们按方向键后要求蛇马上按我们的方向去运动。

kbhit和getch函数都是在库函数conio.h中,注意添加库函数

#include<conio.h>

然后在主函数中进行的更改为

int main()
{
	init();
	int direction=1;
	while(true)
	{
		Print(direction);
		if(kbhit())//判断有键盘指令输入 
		{
			char c=getch();
			if(c=='W')//往上 
			direction=0;
			else if(c=='S')//往下 
			direction=1;
			else if(c=='A')//往左 
			direction=2;
			else if(c=='D')//往右 
			direction=3;
		}
		Sleep(300);//延迟300ms,控制程序显示时间	
	} 
	return 0;
} 

我现在手动输入方向键“W”,“S”,“A”,"D"进行一定方向操作控制,运行结果如下。
在这里插入图片描述
这里备注下,因为截取的动态图没有完全显示,实际显示的内容@后面会有一个白色的光标,因为@是最后一个输出的内容,会跟着一个白色光标,为了美观,我们将白色光标移去其他位置,比如每次在界面外输出gotoxy(x,y,’ '),x和y是在这个墙的范围外的任意一点。
在主函数中添加如下

	while(true)
	{
		Print(direction);
		if(kbhit())//判断有键盘指令输入 
		{
			char c=getch();
			if(c=='W')//往上 
			direction=0;
			else if(c=='S')//往下 
			direction=1;
			else if(c=='A')//往左 
			direction=2;
			else if(c=='D')//往右 
			direction=3;
		}
		gotoxy(X2+1,Y2+1,' ');//为了不在游戏界面中显示白色光标影响界面效果 
		Sleep(300);//延迟500ms,控制程序显示时间	
	} 

4.需要随机生成食物

随机生成食物,也是整个程序最复杂的部分,你以为是简单的随机数生成吗?不是,确实需要随机生成,但是更麻烦的在于,如果随机生成的位置恰好是蛇的身体部分,那么是不对的,重新再生成,但是如果蛇越来越长,那么就会有很大的概率生成的食物和蛇的身体位置冲突,就会导致一直循环判断生成食物不要和蛇的身体冲突,甚至会死循环,因为是随机生成的,你难免会每次都生成的食物位置恰好和蛇的身体都冲突了。

所以怎么随机生成食物,恰好又可以高效的找到不会和蛇的身体冲突的位置呢?

于是我想到了一个有趣的方法,分治处理,我们的地图是二维的,但是可以转换成一维表示,这个没问题,然后我们针对给定的一维坐标范围[L,R]随机生成一个数字X,把X转换成二维坐标,如果这个X对应的二维坐标和蛇的身体冲突了,那么就二分处理,分成[L,X-1]和[X+1,R]两个子区间,再分别在这两个子区间随机找,一直这样下去,就可以很快找到不会和蛇的身体冲突的坐标,递归处理,哈哈哈。
随机递归生成食物代码如下

int food_x,food_y; 
bool search(int L,int R)
{
	if(L>R)return false;
	int MID=random(L,R);
	int d=X2-X1-1;//不能包括围墙,需要把围墙的宽度减去 
	int y=(MID+d)/d+X1;
	int t=MID%d;
	int x=Y1;
	if(t==0)
	x+=d;
	else x+=t; 
	bool flag=false;
	for(int i=0;i<snake.size();i++)
	{
		if(snake[i].x==x&&snake[i].y==y)
		{
			flag=true;
			break;
		}
	}
	if(flag)
	{
		bool res=search(L,MID-1);
		if(res)return true;
		res=search(MID+1,R);
		if(res)return true;
		return false;
	}
	else 
	{
		food_x=x;
		food_y=y;
		return true;
	}
}

目前为止完整代码如下,目前已经可以正常使用,吃食物等,但是没有添加撞墙判断

#include<iostream>
#include<windows.h>
#include<vector>
#include<conio.h>
#include<time.h>
using namespace std;
#define random(a,b) (rand()%(b-a+1)+a)
//在指定位置显示内容 
void gotoxy(int x,int y,char c)
{
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo; //variablendklaration
	HANDLE hConsoleOut;
	hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
	GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
	csbiInfo.dwCursorPosition.X = x; //cursorposition X koordinate festlegen
	csbiInfo.dwCursorPosition.Y = y; //cursorposition Y koordinate festlegen
	SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); //den cursor an die festgelegte koordinate setzen
	printf("%c",c);//输出你指定的字符 
}  
int X1=1,Y1=1;//活动范围的左上角坐标
int X2=60,Y2=30;//活动范围的右下角坐标
struct Snake
{
	int x,y;
};
vector<Snake>snake;
void init()//初始化函数 
{ 
	srand((int)time(0));  // 产生随机种子  把0换成NULL也行
	for(int i=X1;i<=X2;i++)
	{
		gotoxy(i,Y1,'#');
		gotoxy(i,Y2,'#');
	}
	for(int j=Y1;j<=Y2;j++)
	{
		gotoxy(X1,j,'#');
		gotoxy(X2,j,'#');
	}
	snake.clear();//初始化清空	
	Snake t;
	t.x=(X1+X2)/2;
	t.y=(Y1+Y2)/2;
	snake.push_back(t);
} 
//更新的位置,上下左右 
int XX[4]={0,0,-1,1};
int YY[4]={-1,1,0,0};
int food_x,food_y; 
bool search(int L,int R)
{
	if(L>R)return false;
	int MID=random(L,R);
	int d=X2-X1-1;//不能包括围墙,需要把围墙的宽度减去 
	int y=(MID+d)/d+X1;
	int t=MID%d;
	int x=Y1;
	if(t==0)
	x+=d;
	else x+=t; 
	bool flag=false;
	for(int i=0;i<snake.size();i++)
	{
		if(snake[i].x==x&&snake[i].y==y)
		{
			flag=true;
			break;
		}
	}
	if(flag)
	{
		bool res=search(L,MID-1);
		if(res)return true;
		res=search(MID+1,R);
		if(res)return true;
		return false;
	}
	else 
	{
		food_x=x;
		food_y=y;
		return true;
	}
}
void Print(int direction)//显示蛇的内容
{
	int n=snake.size()-1;
	gotoxy(snake[n].x,snake[n].y,' ');//先清除蛇尾留下的痕迹 
	for(int i=n;i>=1;i--)
	snake[i]=snake[i-1];//进行节点更新
	snake[0].x+=XX[direction];
	snake[0].y+=YY[direction]; 
	for(int i=1;i<=n;i++)
	gotoxy(snake[i].x,snake[i].y,'*');
	gotoxy(snake[0].x,snake[0].y,'@');//蛇头用@表示 
	gotoxy(food_x,food_y,'O');
} 
int main()
{
	init();
	int direction=1;
	bool is_food=false;//是否有食物判断
	while(true)
	{
		if(is_food==false)
		{
			search((X1+2)*(Y1+2),(X2-2)*(Y2-2));
			is_food=true;
		}
		Print(direction);
		
		if(snake[0].x==food_x&&snake[0].y==food_y)
		{
			Snake t;
			t.x=food_x,t.y=food_y;
			is_food=false;
			snake.insert(snake.begin(),t);
		}
		if(kbhit())//判断有键盘指令输入 
		{
			char c=getch();
			if(c=='W')//往上 
			direction=0;
			else if(c=='S')//往下 
			direction=1;
			else if(c=='A')//往左 
			direction=2;
			else if(c=='D')//往右 
			direction=3;
		}
		gotoxy(X2+1,Y2+1,' ');//为了不在游戏界面中显示白色光标影响界面效果 
		Sleep(150);//延迟150ms,控制程序显示时间	
	} 
	return 0;
} 

现在的运行结果如下图所示
在这里插入图片描述

现在进行最简单的,就是判断碰撞。

5.判断蛇是否撞到墙或者自己的身体

这里很简单了,就是用蛇头去判断有没有和墙或者自己的身体相撞就可以了,不然就输出游戏结束,也可以自己设计累计得分。

**

最终的完整代码

**

#include<iostream>
#include<windows.h>
#include<vector>
#include<conio.h>
#include<time.h>
using namespace std;
#define random(a,b) (rand()%(b-a+1)+a)
//在指定位置显示内容 
void gotoxy(int x,int y,char c)
{
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo; //variablendklaration
	HANDLE hConsoleOut;
	hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
	GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
	csbiInfo.dwCursorPosition.X = x; //cursorposition X koordinate festlegen
	csbiInfo.dwCursorPosition.Y = y; //cursorposition Y koordinate festlegen
	SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); //den cursor an die festgelegte koordinate setzen
	printf("%c",c);//输出你指定的字符 
}  
int X1=1,Y1=1;//活动范围的左上角坐标
int X2=60,Y2=30;//活动范围的右下角坐标
struct Snake
{
	int x,y;
};
vector<Snake>snake;
void init()//初始化函数 
{ 
	srand((int)time(0));  // 产生随机种子  把0换成NULL也行
	for(int i=X1;i<=X2;i++)
	{
		gotoxy(i,Y1,'#');
		gotoxy(i,Y2,'#');
	}
	for(int j=Y1;j<=Y2;j++)
	{
		gotoxy(X1,j,'#');
		gotoxy(X2,j,'#');
	}
	snake.clear();//初始化清空	
	Snake t;
	t.x=(X1+X2)/2;
	t.y=(Y1+Y2)/2;
	snake.push_back(t);
} 
//更新的位置,上下左右 
int XX[4]={0,0,-1,1};
int YY[4]={-1,1,0,0};
int food_x,food_y; 
bool search(int L,int R)
{
	if(L>R)return false;
	int MID=random(L,R);
	int d=X2-X1-1;//不能包括围墙,需要把围墙的宽度减去 
	int y=(MID+d)/d+X1;
	int t=MID%d;
	int x=Y1;
	if(t==0)
	x+=d;
	else x+=t; 
	bool flag=false;
	for(int i=0;i<snake.size();i++)
	{
		if(snake[i].x==x&&snake[i].y==y)
		{
			flag=true;
			break;
		}
	}
	if(flag)
	{
		bool res=search(L,MID-1);
		if(res)return true;
		res=search(MID+1,R);
		if(res)return true;
		return false;
	}
	else 
	{
		food_x=x;
		food_y=y;
		return true;
	}
}
void Print(int direction)//显示蛇的内容
{
	int n=snake.size()-1;
	gotoxy(snake[n].x,snake[n].y,' ');//先清除蛇尾留下的痕迹 
	for(int i=n;i>=1;i--)
	snake[i]=snake[i-1];//进行节点更新
	snake[0].x+=XX[direction];
	snake[0].y+=YY[direction]; 
	for(int i=1;i<=n;i++)
	gotoxy(snake[i].x,snake[i].y,'*');
	gotoxy(snake[0].x,snake[0].y,'@');//蛇头用@表示 
	gotoxy(food_x,food_y,'O');
} 
bool game_over()
{
	for(int i=1;i<snake.size();i++)
	{
		if(snake[0].x==snake[i].x&&snake[0].y==snake[i].y)return false;
	}
	if(snake[0].x>=X2||snake[0].x<=X1)return false;
	if(snake[0].y>=Y2||snake[0].y<=Y1)return false;
	return true;
}
int main()
{
	init();
	int direction=1;
	bool is_food=false;
	while(true)
	{

		if(is_food==false)
		{
			search((X1+2)*(Y1+2),(X2-2)*(Y2-2));
			is_food=true;
		}
		if(snake[0].x==food_x&&snake[0].y==food_y)
		{
			Snake t;
			t.x=food_x,t.y=food_y;
			is_food=false;
			snake.insert(snake.begin(),t);
		}
		Print(direction);		
		if(game_over()==false)
		{
			gotoxy(X1,Y2+1,' ');
			cout<<"游戏结束!!!\n";
			return 0;
		}
		if(kbhit())//判断有键盘指令输入 
		{
			char c=getch();
			if(c=='W')//往上 
			direction=0;
			else if(c=='S')//往下 
			direction=1;
			else if(c=='A')//往左 
			direction=2;
			else if(c=='D')//往右 
			direction=3;
		}
		gotoxy((X1+X2)/2,Y2+2,' ');//为了不在游戏界面中显示白色光标影响界面效果
		cout<<"当前得分:"<<snake.size()*10<<endl;
		Sleep(150);//延迟150ms,控制程序显示时间	
	} 
	return 0;
} 

运行结果
在这里插入图片描述

后期将写一个有可视化界面的贪吃蛇程序,希望我的分享对你的学习有所帮助,如果有问题请及时指出,谢谢~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

贪吃蛇(一)--用C++编写一个简单的贪吃蛇 的相关文章

  • 如何将 protobuf-net 与不可变值类型一起使用?

    假设我有一个像这样的不可变值类型 Serializable DataContract public struct MyValueType ISerializable private readonly int x private readon
  • 如何让 Swagger 插件在自托管服务堆栈中工作

    我已经用 github 上提供的示例重新提出了这个问题 并为任何想要自己运行代码的人提供了一个下拉框下载链接 Swagger 无法在自托管 ServiceStack 服务上工作 https stackoverflow com questio
  • 如何将非静态类成员“std::bind”绑定到 Win32 回调函数“WNDPROC”?

    我正在尝试将非静态类成员绑定到标准WNDPROC http msdn microsoft com en us library ms633573 aspx功能 我知道我可以通过将类成员设为静态来简单地做到这一点 但是 作为一名 C 11 ST
  • C中的malloc内存分配方案

    我在 C 中尝试使用 malloc 发现 malloc 在分配了一些内存后浪费了一些空间 下面是我用来测试 malloc 的一段代码 include
  • 在 LINQ 中按 Id 连接多表和分组

    我想按categoryId显示列表产品的名称组 这是我的代码 我想要我的视图显示结果 Desktop PC HP Red PC Dell Yellow PC Asus Red SmartPhone Lumia 720 Blue 我的组模型
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 为什么 Google 测试会出现段错误?

    我是 Google Test 的新手 正在尝试提供的示例 我的问题是 当我引入失败并设置GTEST BREAK ON FAILURE 1 或使用命令行选项 GTest 将出现段错误 我正在考虑这个例子 https code google c
  • DbContext 和 ObjectContext 有什么区别

    From MSDN 表示工作单元和存储库模式的组合 使您能够查询数据库并将更改分组在一起 然后将这些更改作为一个单元写回存储 DbContext在概念上类似于ObjectContext 我虽然DbContext只处理与数据库的连接以及针对数
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • 如何禁用 fread() 中的缓冲?

    我正在使用 fread 和 fwrite 读取和写入套接字 我相信这些函数用于缓冲输入和输出 有什么方法可以在仍然使用这些功能的同时禁用缓冲吗 Edit 我正在构建一个远程桌面应用程序 远程客户端似乎 落后于服务器 我不知道可能是什么原因
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • 使用管道时,如果子进程数量大于处理器数量,进程是否会被阻塞?

    当子进程数量很大时 我的程序停止运行 我不知道问题是什么 但我猜子进程在运行时以某种方式被阻止 下面是该程序的主要工作流程 void function int process num int i initial variables for
  • 为什么 gcc 抱怨“错误:模板参数 '0' 的类型 'intT' 取决于模板参数”?

    我的编译器是gcc 4 9 0 以下代码无法编译 template
  • 调用堆栈中的“外部代码”是什么意思?

    我在 Visual Studio 中调用一个方法 并尝试通过检查调用堆栈来调试它 其中一些行标记为 外部代码 这到底是什么意思 方法来自 dll已被处决 外部代码 意味着该dll没有可用的调试信息 你能做的就是在Call Stack窗口中单
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看
  • 当从finally中抛出异常时,Catch块不会被评估

    出现这个问题的原因是之前在 NET 4 0 中运行的代码在 NET 4 5 中因未处理的异常而失败 部分原因是 try finallys 如果您想了解详细信息 请阅读更多内容微软连接 https connect microsoft com

随机推荐

  • android接入opencv方式

    原网址 https www cnblogs com xiaoxiaoqingyi p 6676096 html Android 接入 OpenCV库的三种方式 OpenCV是一个基于BSD许可 开源 发行的跨平台计算机视觉库 可以运行在Li
  • 按键控制数码管加减清零

    实验说明 实验接线 独立按键模块 gt 单片机管脚 K1 gt P31 K2 gt P30 K3 gt P32 K4 gt P33 未使用 大家可以自己扩展功能 动态数码管模块 gt 单片机管脚 参考动态数码管实验接线 开发攻略内在对应的实
  • 【任务调度系统第二篇】:XXL Job源码分析

    文章目录 写在前面 一 XXL JOB项目源码整体概括 1 源码整体概括说明 2 分析该项目源码时一些必须的知识 2 1 quartz简单介绍 2 2 freemarker前端渲染模板简介 2 3 java基本功修炼 二 xxl job a
  • Vscode编辑器下显示图片遇到的问题

    在编辑器Vscode下显示jpg图片不成功 测试代码和提示错误信息如下图 但是在IDLE中进行如上操作却能正常显示 Python环境为anaconda PIL matplotlib 问题出在什么地方呢
  • 算法1:一个无序的int数组,包含正负数, 排序成:左边为负数 右边为正数

    public class MinusPlubs public static void minusLeftPlusRight int nums int p1 1 boolean firstTime true for int i 0 i lt
  • D2D通信的Matlab关键技术

    D2D通信的Matlab关键技术 D2D Device to Device 通信是一种直接在终端设备之间进行通信的技术 它可以提供高效的通信和资源共享 在本文中 我们将介绍D2D通信的一些关键技术 并使用Matlab提供相应的源代码来实现这
  • 利用Power BI计算组,设计个性化数据标签

    利用Power BI计算组 设计个性化数据标签 知乎 zhihu com https zhuanlan zhihu com p 405532292
  • Exception 开发遇见异常

    1 java lang OutOfmemoryError 原因 常见的有以下几种 1 内存中加载的数据量过于庞大 如一次从数据库取出过多数据 2 集合类中有对对象的引用 使用完后未清空 使得JVM不能回收 3 代码中存在死循环或循环产生过多
  • TCP协议如何保证可靠传输

    TCP的功能是交付数据 所以TCP的可靠就是保证每次数据按序 按时 不丢数据 顺利的交付给对端 可靠不等于安全 TCP尽最大可能的保证数据可靠性 但是没有任何措施保证数据的安全性 所谓安全就是你的数据不会被别人看到或者窃取到 TCP上的数据
  • Ubuntu安装Redis集群(主从+哨兵)

    一 下载 官网 Download Redis 百度云 链接 https pan baidu com s 1sQjpbiFIFhnSpa0 uCP53A 提取码 AA56 版本 redis 6 23 注 本文依旧此博文修改而来 那篇更为详细
  • 使用Java实现七牛云OSS云存储上传图片至指定目录

    使用Java实现七牛云OSS云存储上传图片至指定目录 思路介绍 Controller代码 Util工具类代码 配置类 配置对象QnOssProperties 思路介绍 首先介绍下我的实现思路 前端通过Controller调用上传方法 上传方
  • 深分页优化总结

    前言 最近有面试过也遇到了问关于深分页问题 在这里简单从MySQL ES等方面分享一下自己对该问题认识和总结 一 深分页定义 可以从ES定义上来划分浅分页和深分页的边界 即页数超过10000页为深分页 少于10000页为浅分页 二 MySQ
  • QT打包发布全流程,超详细

    目录 第一步 配置环境变量 这一步不会的可以看我另一篇文章 QT 打包发布之环境变量配置 简单四步搞定 第三步 进行初步测试 主演是看你的程序是否有错 第四步 程序能运行 就可以在上层目录中看到生成了一个release文件夹 第五步 点开文
  • LeetCode周赛总结 第277场

    本文同步发布在我的个人博客 LeetCode周赛总结 第277场 欢迎访问 本次周赛没想到比上周还要简单 前三题都可以用非常简单的方法快速解决 第四题如果想对了方向其实也比较简单 元素计数 题目链接 元素计数 解题思路 相当基础的题目 要同
  • 华为OD机试 - 最佳植树距离(Java)

    题目描述 按照环保公司要求 小明需要在沙化严重的地区进行植树防沙工作 初步目标是种植一条直线的树带 由于有些区域目前不适合种植树木 所以只能在一些可以种植的点来种植树木 在树苗有限的情况下 要达到最佳效果 就要尽量散开种植 不同树苗之间的最
  • 【Java script基础学习】本地对象 - Date

    Date 日期对象 用来操作计算机的日期和时间 获取 获取当前日期时间 获取当前的时间戳 Date now 时间戳 从1970 1 1 0 0 0 到此刻的毫秒数 获取完整的日期对象 new Date 获取到的是一个对象类型的日期 包含日期
  • STM32MP157驱动开发——Linux LCD驱动(上)

    STM32MP157驱动开发 Linux LCD驱动 上 0 前言 一 LCD 和 LTDC 简介 1 LCD 简介 1 分辨率 2 像素格式 3 LCD 屏幕接口 4 LCD 时间参数 5 RGB LCD 屏幕时序 6 像素时钟 7 显存
  • 【Python pygame】零基础也能轻松掌握的学习路线与参考资料

    Python pygame是一款专门用于开发游戏和多媒体应用程序的Python库 它可以帮助开发者实现丰富多彩的图形界面和实时动态交互效果 本篇文章将为大家介绍Python pygame的学习路线 包括入门基础 进阶知识以及优秀实践 帮助大
  • C++中return语句的用法

    C 中的return语句是函数中一个重要的语句 return语句用于结束当前正在执行的函数 并将控制权返回给调用此函数的函数 return语句有两种形式 return return expression 1 没有返回值的函数 不带返回值的r
  • 贪吃蛇(一)--用C++编写一个简单的贪吃蛇

    这里简单介绍怎么用C 编写一个简单的黑白框的贪吃蛇游戏 复杂的加了可视化界面程序点击这里贪吃蛇 二 easyX图形库进行可视化界面制作 首先分析在黑白框中的贪吃蛇需要哪些功能 1 需要能在界面指定位置 x y 直接输出对应内容 2 需要动态