user-0 提问: 求助！！！C语言版的贪吃蛇问题，谢谢。

回复:
user: user-1
content: 学习一下#3楼的代码。

user: user-2
content: 我大概看了下，就结果而言，我还是不懂。 通过调试我发现不管两次按键时间多么接近，在循环的时候中间总是会出现一次按键识别不了， 比如我一打开就输入 左 下。 _getchar() 两次循环的值：75、80 可是实际上是：75、-32、80 中间多了一次是-32，然后多走了一步。 我简单修改了下RunGame()  void RunGame() { 	while (1) 	{ 		/////////////////////////////// 		COORD pos_1 = { Wid + 2,4 }; 		char a = 0; 		if (_kbhit()) 		{ 			a = _getch(); 			if (a == -32) 			{ 				continue; 			}  		}  		switch (a) 		{ 		case 72: 			if (HeadPos.dir != 1) 			{ 				HeadPos.dir = 0;//上 			} 			break; 		case 80: 			if (HeadPos.dir != 0) 			{ 				HeadPos.dir = 1;//下 			} 			break; 		case 75: 			if (HeadPos.dir != 3) 			{ 				HeadPos.dir = 2;//左 			} 			break; 		case 77: 			if (HeadPos.dir != 2) 			{ 				HeadPos.dir = 3;//右 			} 			break; 		case 'a': 			pos_1.Y = 8; 			GetPosition(pos_1); 			system("pause"); 			GetPosition(pos_1); 			printf("                "); 			GetPosition(pos_1); 			printf("按a键暂停游戏"); 			break; 		case '5': 			speed = 50; 			GetPosition(pos_1); 			printf("当前模式：噩梦"); 			break; 		case '4': 			speed = 100; 			GetPosition(pos_1); 			printf("当前模式：困难"); 			break; 		case '3': 			speed = 150; 			GetPosition(pos_1); 			printf("当前模式：一般"); 			break; 		case '2': 			speed = 200; 			GetPosition(pos_1); 			printf("当前模式：简单"); 			break; 		case '1': 			speed = 1000; 			GetPosition(pos_1); 			printf("当前模式：蜗牛"); 			break; 		}  		switch (HeadPos.dir) 		{ 		case 0: 			HeadPos.pos.Y--; 			break; 		case 1: 			HeadPos.pos.Y++; 			break; 		case 2: 			HeadPos.pos.X -= 2; 			break; 		case 3: 			HeadPos.pos.X += 2; 			break; 		} 		/////////////////////////////// 		 		if (GameOver()) 		{ 			break; 		} 		else if (HeadPos.pos.X == Food.X&&HeadPos.pos.Y == Food.Y) 		{ 			AddSnakeBody(HeadPos.pos); 			InitFood(); 		} 		else 		{ 			MoveSnake(HeadPos.pos); 		}  		Sleep(speed); 	} 	COORD pos = { 0,Hei }; 	GetPosition(pos); 	printf("很遗憾，你撞墙了或者自食自己，游戏结束!\n"); }  判断并把-32的值跳过， 然后效果差不多了。  我原以为是_kbhit()和_getch()这两个函数的特点， 可是我新建了一个项目，简单地搭建了类似的场景，测试结果却没有上面那种问题。 这个问题……搞不懂了。 我也是有点好奇，请路过的高手回答吧。

user: user-3
content: 总的来说，要考虑按键的时序和Sleep在主循环中的位置的关系。

user: user-1
content: 仅供参考：#include <conio.h> #include <windows.h>  void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); } void HideTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = FALSE;       SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  void ShowTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = TRUE;       SetConsoleCursorInfo(hStdOut, &cciCursor);    } } void GetWH(int *w,int *h) {     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     CONSOLE_SCREEN_BUFFER_INFO csbi;     if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) {         *w=csbi.srWindow.Right;         *h=csbi.srWindow.Bottom;     } else {         *w=80;         *h=25;     } } void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  int main() {     unsigned short k;     int x,y,w,h;     char d;      SetConsoleOutputCP(437);     ClearConsole();     GetWH(&w,&h);     x=w/2;y=h/2;     HideTheCursor();     ConPrintAt(x,y,"O",1);     d='o';     while (1) {         Sleep(50);         if (kbhit()) {             k=getch();             if (27==k) break;//按Esc键退出             if (0==k||0xe0==k) k|=getch()<<8;//非字符键             switch (k) {                 case 0x48e0:case 0x04800://上                     d='u';                     if (y>0) {                         ConPrintAt(x,y," ",1);                         y--;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 0x50e0:case 0x05000://下                     d='d';                     if (y<h) {                         ConPrintAt(x,y," ",1);                         y++;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 0x4be0:case 0x04b00://左                     d='l';                     if (x>0) {                         ConPrintAt(x,y," ",1);                         x--;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 0x4de0:case 0x04d00://右                     d='r';                     if (x<w-1) {                         ConPrintAt(x,y," ",1);                         x++;                         ConPrintAt(x,y,"O",1);                     }                 break;             } //          cprintf("%04x pressed.\r\n",k);         } else {             switch (d) {                 case 'u':                     if (y>0) {                         ConPrintAt(x,y," ",1);                         y--;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 'd':                     if (y<h) {                         ConPrintAt(x,y," ",1);                         y++;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 'l':                     if (x>0) {                         ConPrintAt(x,y," ",1);                         x--;                         ConPrintAt(x,y,"O",1);                     }                 break;                 case 'r':                     if (x<w-1) {                         ConPrintAt(x,y," ",1);                         x++;                         ConPrintAt(x,y,"O",1);                     }                 break;             }         }     }     ClearConsole();     ShowTheCursor();     return 0; }

user: user-4
content: 单步调试是程序员的基本技能，转弯的时候下个断点看一下