基于linux的c语言版本的俄罗斯方块

文章目录

  • 基于linux的c语言版本的俄罗斯方块
  • 前言
  • 一、前期准备
  • 二、使用步骤
    • 1.创建俄罗斯方块DATA库
    • 2.函数声明
    • 3.创建时钟定时器
    • 4.游戏区域初始化
    • 5. 画一个方块
    • 6.刷新游戏区域
    • 7.清除一个方块
    • 8.检测方块是否可以移动
    • 9.检查游戏是否结束
    • 10.检查是否可以消行
    • 11.定时器的信号函数
    • 12.方块旋转
    • 13.游戏暂停
    • 14.主函数main
  • 总结

前言

提示:这里可以添加本文要记录的大概内容:

在参考了诸多大神的程序之后,自己写了一个基于linux的c语言俄罗斯方块教程


提示:以下是本篇文章正文内容,下面案例可供参考

一、前期准备

游戏有wsad控制方向,空格暂停游戏,q为结束游戏。
下面为游戏的所有代码和代码解释。

二、使用步骤

1.创建俄罗斯方块DATA库

首先需要一个数据库来保存俄罗斯方块中的7中基本方块而且每种方块有4中变形,故需要保存28种方块模型,每种模型采用一个二维数组保存
/************************************************** 文件名: Data.h* 功能描述:俄罗斯方块游戏的方块数据库
*************************************************/
#ifndef  _DATA_H_
#define  _DATA_H_#define    NR    4  // 方块数据大小
#define    TYPE  7  // 方块类型数/* 方块数据 */
char bl[TYPE][NR][NR][NR] = {/* 第一种方块 */{{ /* 第一种方向 */{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0},},{ /* 第二种方向 */{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0},},{ /* 第三种方向 */{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0},},{ /* 第四种方向 */{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0},},},/* 第二种方块 */{{ /* 第一种方向 */{2,2,2,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},},{ /* 第二种方向 */{0,2,0,0},{0,2,0,0},{0,2,0,0},{0,2,0,0},},{ /* 第三种方向 */{2,2,2,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},},{ /* 第四种方向 */{0,2,0,0},{0,2,0,0},{0,2,0,0},{0,2,0,0},},},/* 第三种方块 */{{ /* 第一种方向 */{3,0,0,0},{3,3,3,0},{0,0,0,0},{0,0,0,0},},{ /* 第二种方向 */{0,3,3,0},{0,3,0,0},{0,3,0,0},{0,0,0,0},},{ /* 第三种方向 */{3,3,3,0},{0,0,3,0},{0,0,0,0},{0,0,0,0},},{ /* 第四种方向 */{0,0,3,0},{0,0,3,0},{0,3,3,0},{0,0,0,0},},},/* 第四种方块 */{{ /* 第一种方向 */{0,0,4,0},{4,4,4,0},{0,0,0,0},{0,0,0,0},},{ /* 第二种方向 */{0,4,0,0},{0,4,0,0},{0,4,4,0},{0,0,0,0},},{ /* 第三种方向 */{0,4,4,4},{0,4,0,0},{0,0,0,0},{0,0,0,0},},{ /* 第四种方向 */{0,4,4,0},{0,0,4,0},{0,0,4,0},{0,0,0,0},},},/* 第五种方块 */{{ /* 第一种方向 */{0,5,0,0},{5,5,5,0},{0,0,0,0},{0,0,0,0},},{ /* 第二种方向 */{0,5,0,0},{0,5,5,0},{0,5,0,0},{0,0,0,0},},{ /* 第三种方向 */{5,5,5,0},{0,5,0,0},{0,0,0,0},{0,0,0,0},},{ /* 第四种方向 */{0,5,0,0},{5,5,0,0},{0,5,0,0},{0,0,0,0},},},/* 第六种方块 */{{ /* 第一种方向 */{6,6,0,0},{0,6,6,0},{0,0,0,0},{0,0,0,0},},{ /* 第二种方向 */{0,0,6,0},{0,6,6,0},{0,6,0,0},{0,0,0,0},},{ /* 第三种方向 */{6,6,0,0},{0,6,6,0},{0,0,0,0},{0,0,0,0},},{ /* 第四种方向 */{0,0,6,0},{0,6,6,0},{0,6,0,0},{0,0,0,0},},},/* 第七种方块 */{{ /* 第一种方向 */{0,7,7,0},{7,7,0,0},{0,0,0,0},{0,0,0,0},},{ /* 第二种方向 */{0,7,0,0},{0,7,7,0},{0,0,7,0},{0,0,0,0},},{ /* 第三种方向 */{0,0,7,7},{0,7,7,0},{0,0,0,0},{0,0,0,0},},{ /* 第四种方向 */{0,7,0,0},{0,7,7,0},{0,0,7,0},{0,0,0,0},},},
};#endif   //_DATA_H_

2.函数声明

函数声明
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include "data.h"#define   ROW    21     // 游戏区域的行数
#define   COL    18     // 游戏区域的列数i
/***** 函数声明区域 ******/
void initalGameArea(void);                  // 初始化游戏区域
void drawBlock(char block[NR][NR]);            // 画方块
void cleanBlock(char block[NR][NR]);           // 清除方块
void turnBlock(char block[NR][NR]);            // 旋转方块
void gameEnd(void);                         // 结束游戏
void gameStop(void);                        // 暂停游戏
void showGame(void);                        // 显示游戏
void gameSelf(int signo);                   // 游戏自动运行
void checkDeleteLine(void);                 // 检查是否满一行
void checkGameOver(char bl[NR][NR]);        // 检查是否游戏结束
int  checkMove(char bl[NR][NR], int flag);  // 检查方块是否可移动
int  getInput(void);                        // 获取输入
/* 全局变量区域 */
static char gameArea[ROW][COL] = {0};      // 游戏区域数据
static int startX = 7, startY = 6;        // 方块出现的起始位置
static char type = 0;                      // 方块当前类型
static char nextType = 0;                  // 方块的下一种类型
static int diret = 0;                      // 方块的方向
static unsigned int level = 0;             // 游戏等级
static unsigned int score = 0;             // 游戏分数
static unsigned int maxScore = 0;          // 游戏最高记录
char *state = "\033[32m游戏中...\033[0m";   // 游戏运行状态/* 按键枚举 */
enum key {DOWN,             // 上LEFT,               // 左RIGHT,              // 右CHANGE,             // 变化STOP,              // 停止EXIT,              // 退出UNKNOW,            // 未知
};

3.创建时钟定时器

实现俄罗斯方块要求是方块能够一边下落一边控制方块变形和移动,这就要求需要并发        {{0,700000},{0,700000}}; :第一个是间歇值,第二个是初始值
[itimerval  详细说明](https://simple.blog.csdn.net/article/details/72718055?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-72718055-blog-108609163.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-72718055-blog-108609163.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=2)
  struct itimerval  timer = {{0,700000},{0,700000}};setitimer(ITIMER_REAL, &timer,NULL);/* 初始化方块类型 */signal(SIGALRM, gameSelf);//中断信号 每0.7s进入一次gameSelf函数
创建了一个每0.7s就产生一次的定时器,该定时器触发之后 会 执行gameSelf()函数,控制俄罗斯方块的下降,而在mian函数的while循环中控制方块移动和变形。

4.游戏区域初始化

我们首先需要对屏幕进行操作,代码如下
printf("\033[2J");           // 清屏system("stty -icanon");          // 关缓冲system("stty -echo");       // 关回显fprintf(stdout,"\033[?25l");  // 关闭鼠标显示

然后需要规划游戏区域,游戏区域是一块二维数组 gameArea[][],代码如下

/** 函数名:initalGameArea* 函数功能:初始化游戏区域* 参数:无* 返回值:无
*/
void initalGameArea(void)
{int i;/* 屏幕设置 */printf("\033[2J");             // 清屏system("stty -icanon");          // 关缓冲system("stty -echo");       // 关回显fprintf(stdout,"\033[?25l");  // 关闭鼠标显示/* 初始化行 */for (i = 0; i < COL; i++){gameArea[0][i]     = 8;   // 第0行gameArea[5][i]     = 8;   // 第5行gameArea[ROW-1][i] = 8;   // 最后一行}/* 初始化列 */for (i = 0; i < ROW; i++){gameArea[i][0]     = 8;  // 第0列gameArea[i][COL-1] = 8;  // 最后一列}/* 中间一小列 */for (i = 1; i < 5; i++){gameArea[i][6] = 8;}
}

规划游戏区域效果图

5. 画一个方块

讲数据库中的一个数字数组所代表的方块填入游戏区域数组gameArea[][]数组中的指定位置

/** 函数名:drawBlock* 函数功能:填充方块数据* 参数:方块数组数据* 返回值:无
*/
void drawBlock(char block[NR][NR])//将bl[nextType][diret]对应的二维数组的值赋给 block[NR][NR]
{int x, y;/* 画当前方块 */for (y = 0; y < 4; y++){for (x = 0; x < 4; x++){if ( block[y][x] != 0){gameArea[startY+y][startX+x] = block[y][x];}}}/* 画提示的下一个方块 */for (x = 0; x <2 ; x++)//每种方块的第一种均只占两行{for (y = 0; y < 4; y++){if (bl[nextType][0][x][y] != 0)gameArea[3+x][2+y] = bl[nextType][0][x][y];elsegameArea[3+x][2+y] = 0;}}
}

6.刷新游戏区域

显示游戏区域和局内信息并刷新游戏区域内的方块位置

/** 函数名:showGame* 函数功能:显示游戏* 参数:无* 返回值:无
*/
void showGame(void)
{int i, j;/* 定位到第一行第一列 */fprintf(stdout,"\033[1;1H");fflush(stdout);/* 打印所有数据 */for (i = 0; i < ROW; i++){for (j = 0; j < COL; j++){if (gameArea[i][j] == 0)       // 空白区域{fprintf(stdout,"  ");}else if (gameArea[i][j] == 8)  // 边界区域{fprintf(stdout,"\033[43m  \033[0m");}else                           // 方块区域{fprintf(stdout,"\033[%dm[]\033[0m",gameArea[i][j]+40);}}fputc('\n',stdout);}/* 打印提示信息 */fprintf(stdout,"\033[2;3H\033[33m【下一个】\033[0m\n");fprintf(stdout,"\033[2;15H当前级别:\033[36m%u\033[0m\n",level);fprintf(stdout,"\033[3;15H当前分数:\033[32m%u\033[0m\n",score);fprintf(stdout,"\033[4;15H最高记录:\033[35m%u\033[0m\n",maxScore);fprintf(stdout,"\033[5;15H当前状态:%s\n",state);
}

7.清除一个方块

我们程序执行过程一定是 画方块------->刷新游戏区域,在屏幕上显示方块------>清除方块
注意:清除方块只是将 该方块的位置从 gameArea[startY+y][startX+x]=0数组 中将其方块所占位置清零,但是屏幕上仍然存在,只有在下一个刷新屏幕之后才会更新

/** 函数名:cleanBlock* 函数功能:清除方块数据* 参数:方块数组数据* 返回值:无
*/
void cleanBlock(char block[NR][NR]){int x,y;  for (y = 0; y < NR; y++){for (x = 0; x < NR; x++){if(block[y][x]!=0)       {gameArea[startY+y][startX+x]=0;          }}}
}

8.检测方块是否可以移动

能移则移动。
注意;定时器中会0.7s产生一次向下移动,在向下移动时,移动不了则判断游戏是否结束,没结束说明方块到底,需保存方块位置

/** 函数名:checkMove* 函数功能:检查方块是否可移动,能移则移* 参数:1.方块数组数据 2.方向标志位* 返回值:可移动返回1,不能移动返回0
*/
int checkMove(char block[NR][NR], int flag)
{int d, lr;   // 用于标明可移动方向  d表示向下 lr=1表示右  lr=-1表示左int x, y;   // 用于循环switch (flag) //事件可以由键盘触发 也可以直接输入flag值触发事件{case RIGHT: d=0;lr=1;break;case LEFT: d=0;lr=-1;break;case DOWN : d=1;lr=0;break;}for(y=0;y<4;y++){for (x=0;x<4;x++){if (block[y][x] !=0 && gameArea[startY+y+d][startX+x+lr] != 0)//不能移return 0;}}//方块初始位置发生变化startX+=lr;startY+=d;return 1;
}

9.检查游戏是否结束

如果方块区域已经触碰到顶端则判定游戏结束

/** 函数名:checkGameOver* 函数功能:检查游戏是否结束* 参数:待检查方块数据数据* 返回值:无
*/
void checkGameOver(char block[NR][NR])
{int y;for(y=0;y<4;y++){if(block[0][y] !=0 && gameArea[startY-1][startX+y]==8){gameEnd();//游戏结束}}
}

如果游戏结束则调用gameEed函数来退出游戏

/** 函数名:gameEnd* 函数功能:处理游戏结束的设置* 参数:无* 返回值:无
*/
void gameEnd(void)
{/* 配置游戏结束后的界面 */state = "\033[31m游戏结束!!\033[0m";drawBlock(bl[type][diret]);showGame();/* 恢复终端设置 */system("stty icanon");          // 恢复缓冲system("stty echo");            // 恢复回显fprintf(stdout,"\033[?25h");    // 恢复鼠标显示exit(0);                        // 退出程序
}

10.检查是否可以消行

在方块判断到达底部时需要判断是否能够消行

/** 函数名:checkDeleteLine* 函数功能:检查是否可消行* 参数:无* 返回值:无
*/
void checkDeleteLine(void)
{int i, j;int x, y;/* 检查当前方块的四行区域内 */for (i = 3; i >= 0; i--){for (j = 1; j < COL-1; j++){/* 检测方块是否满一行 */if (gameArea[startY+i][j] == 0)//从方块最下层依次检查 等于0说明该行为空 不能消行break;/* 跳过边框区域 */else if (gameArea[startY+i][j] == 8)//如果检查到了边框说明没有课消除的行break;}/* 如果满了一行则删除一行 */if (j == COL-1){/* 删除满了的一行 */for (j = 1; j < COL-1; j++){gameArea[startY+i][j] = 0;//消除第i行}/* 分数累加 */score += 100;/* 记录最高分 */if (score > maxScore){maxScore = score;}/* 记录级别 */if (score%200 == 0){/* 每200分加一级 */level++;}/* 删除后往下移动一行 */for (x = 1; x < COL-1; x++){for (y = startY+i; y >= 7; y--){gameArea[y][x] = gameArea[y-1][x];}}//删除一行之后需要重新再次检索该行能不能消行i++;}}
}

11.定时器的信号函数

系统每0.7s会访问一次定时器信号函数在定时器信号函数中我们需要执行的操作有:画方块----->刷新游戏区域----->清除方块----->方块下降并保存方块当前位置----->判断是否下降到底----->下降到底判断游戏是否结束----->游戏未结束则保存底部方块----->保存之后刷新游戏区域----->判断是否能消行----->不管是否能消行,产生一个新的方块

/** 函数名:checkDeleteLine* 函数功能:检查是否可消行* 参数:无* 返回值:无
*/
void checkDeleteLine(void)
{int i, j;int x, y;/* 检查当前方块的四行区域内 */for (i = 3; i >= 0; i--){for (j = 1; j < COL-1; j++){/* 检测方块是否满一行 */if (gameArea[startY+i][j] == 0)//从方块最下层依次检查 等于0说明该行为空 不能消行break;/* 跳过边框区域 */else if (gameArea[startY+i][j] == 8)//如果检查到了边框说明没有课消除的行break;}/* 如果满了一行则删除一行 */if (j == COL-1){/* 删除满了的一行 */for (j = 1; j < COL-1; j++){gameArea[startY+i][j] = 0;//消除第i行}/* 分数累加 */score += 100;/* 记录最高分 */if (score > maxScore){maxScore = score;}/* 记录级别 */if (score%200 == 0){/* 每200分加一级 */level++;}/* 删除后往下移动一行 */for (x = 1; x < COL-1; x++){for (y = startY+i; y >= 7; y--){gameArea[y][x] = gameArea[y-1][x];}}//删除一行之后需要重新再次检索该行能不能消行i++;}}
}/** 函数名:gameSelf* 函数功能:作为信号函数,闹钟时间一到就自动下落* 参数:信号* 返回值:无
*/
void gameSelf(int signo)
{/* 画方块 */drawBlock(bl[type][diret]);/* 显示游戏 */showGame();//刷新游戏界面/* 清除方块 */cleanBlock(bl[type][diret]);//清除所画的方块,在下一次界面刷新时生效if(!checkMove(bl[type][diret],DOWN)) //每0.7s下移一次 判断是否能够下移 如果不能够下移则进入if{checkGameOver(bl[type][diret]);//检查游戏是否结束 如果游戏没结束说明下移到底drawBlock(bl[type][diret]);/* 保留已经到底的方块 */showGame();//刷新一下显示界面/* 到达边界后检查是否可消行 */checkDeleteLine();/*不管是否能消行,该方块已经结束,重新开始新的方块*/startX=7;startY=6;type = nextType;nextType = rand()%7;diret = 0;}
}

12.方块旋转

在方块旋转时需要判断旋转之后的图形是否越界,如果越界则旋转失败
/** 函数名:turnBlock* 函数功能:旋转方块* 参数:需要旋转的方块数组数据* 返回值:无
*/
void turnBlock(char bl[NR][NR])
{int x, y;/* 检查是否越界 */for (y = 0; y < NR; y++){for (x = 0; x < NR; x++){/* 只能判断到达了边界 */if (bl[y][x] != 0 && gameArea[startY+y][startX+x+1] != 0 ){return;}}}/* 两边都没有越界则旋转方块方向 */diret = (diret+1)%4;
}

13.游戏暂停

游戏暂停就是将定时器取消
linux下取消用setitimer设置的定时器只需要将间歇值置零即可
/** 函数名:gameStop* 函数功能:暂停游戏,等待用户再次启动游戏* 参数:无* 返回值:无
*/
void gameStop(void)
{/* 创建一个暂停的是时钟 */struct itimerval stop = {0}, older;/* 设置新闹钟并存储旧闹钟 */setitimer(ITIMER_REAL,&stop,&older);/* 配置暂停后的界面 */state = "\033[31m暂停中...\033[0m";startY--;             // 为了防止按下暂停键后方块下滑一格drawBlock(bl[type][diret]);showGame();cleanBlock(bl[type][diret]);/* 等待用户按开始键或退出键 */int key;while (1){key = fgetc(stdin);/* 空格开始 */if (key == ' ')break;/* q 退出 */else if (key == 'q')gameEnd();}/* 恢复闹钟和游戏 */setitimer(ITIMER_REAL,&older,NULL);state = "\033[32m游戏中...\033[0m";
}

14.主函数main

在主函数中我们需要读取键盘输入来控制方块移动、变形、游戏的暂停、结束


int main()
{/** 设置闹钟:* 当前时间间隔为0.7秒,下一次时间间隔为0.7秒*/struct itimerval  timer = {{0,700000},{0,700000}};setitimer(ITIMER_REAL, &timer,NULL);initalGameArea();//游戏区域初始化/* 初始化方块类型 */signal(SIGALRM, gameSelf);//中断信号 每0.7s进入一次gameSelf函数/* 初始化方块类型 */srand(time(NULL));type     = rand()%7;nextType = rand()%7;while(1){int     key = getInput();switch (key){case RIGHT : checkMove(bl[type][diret],RIGHT);break;case LEFT  : checkMove(bl[type][diret],LEFT);break;case DOWN  : checkMove(bl[type][diret],DOWN);break;case CHANGE: turnBlock(bl[type][(diret+1)%4]);break;case STOP  : gameStop();break;case EXIT  : gameEnd();break;case UNKNOW: continue;}/*执行玩输入指令后重新 画方块 */drawBlock(bl[type][diret]);/* 显示游戏 */showGame();//刷新游戏/* 清除方块 */cleanBlock(bl[type][diret]);}return 0;
}
键盘插入函数如下
/** 函数名:getInput* 函数功能:获取用户输入* 参数:无* 返回值:无
*/
int getInput(void)
{char key;key = fgetc(stdin);//函数会阻塞等待键盘输入 等同于 getchar()if(key=='w')return CHANGE;else if(key=='s')return DOWN;else if(key=='a')return LEFT;else if(key=='d')return RIGHT;else if (key == 'q')    // 退出键{return EXIT;}else if (key == ' ')    // 空格键-暂停游戏{return STOP;}else                    // 其它不相关的键return UNKNOW;
}

总结

提示:这里对文章进行总结:

。如果懒得看,想直接使用程序,我把整个游戏打包放到了我的资源,可直接使用

基于linux的c语言版本的俄罗斯方块相关推荐

  1. linux系统c 如何使用教程,基于Linux操作系统的C语言编译和调试方法解析

    摘 要:文章先介绍了GCC编译器相关内容,包括GCC编译程序和GCC编译选项,随后介绍了GDB调试程序相关内容,包括GDB具体操作和GDB基础命令,最后介绍了C语言编写中的注意事项,希望能给相关人士提 ...

  2. 基于Windows10基于Linux的C语言笔记Ⅰ

    这玩意儿就是自己的学习笔记,不过,也可以用来入门学习C语言.However,你需要: 学习C语言兴致, Windows10(或者你有一台Linux系统的电脑), 会用vim/vi.nano或者(其实会 ...

  3. 基于Windows10基于Linux的C语言笔记Ⅱ

    WHAT YOU NEED: 安装 WSL 1 的 Win 10 或是 Linux: GNU 的 C/C++ 编译器(gcc): vim/vi.nano等编辑器. (或者你有一个自己熟悉的系统与IDE ...

  4. 基于Linux用C语言实现TCP半双工通信和UDP半双工通信

    文章目录 TCP协议/UDP协议介绍 三种通信方式 实现TCP半双工通信 所用到的结构体与函数 源代码 运行结果 实现UDP半双工通信 源代码 运行结果 参考文章 TCP协议/UDP协议介绍 TCP/ ...

  5. 基于linux用C语言编写的局域网通信软件(在ubuntu上正常运行)

    /************************************************************ 去年学C语言socket通信时花三天时间写的. 功能 A,私聊 B,群聊,C ...

  6. C语言运行超过运行限制,程序中的一些限制(基于Linux系统C语言)

    今天突然想起来几个问题,在程序运行起来时,存在一些限制: 1,数组的长度(成员的个数)存在限制!(数组定义的空间大小) 2,一个进程里打开的文件数. 3,一个文件的名字的长度. 4,一个进程里创建线程 ...

  7. 基于Linux的c语言知识

    一,指针的概念 指针也就是内存地址,指针变量是用来存放内存地址的变量,在同- -CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变因数据的类型不同,所占用的存储空间长度也不同 ...

  8. 操作系统大作业 基于Linux的模拟进程调度算法 运用c++语言编程 在VMware虚拟机里 centos 亲自写亲自测试 代码 说明书

    发布文章 博文管理我的博客退出 Trash Temp 操作系统大作业 基于Linux的模拟进程调度算法 运用c++语言编程 在VMware虚拟机里 centos 亲自写亲自测试 代码 说明书 @[TO ...

  9. 限速linux c语言,基于Linux系统的流量控制程序的C语言代码

    基于Linux系统的流量控制程序的C语言代码 基于Linux系统的流量控制程序的C语言代码 mytbf.h头文件 ifndef MYTBF_H_ #define MYTBF_H_ typedef vo ...

最新文章

  1. linux进程间通信-XSI IPC
  2. 浙大博士导师整理:Tensorflow和Pytorch的笔记(包含经典项目实战)
  3. 上拉电阻下拉电阻高阻态
  4. datagridview输入字符串的格式不正确_Python3试学:输入和输出(1)
  5. GIS实用小技巧(三)-CASS怎么添加图例?
  6. 度量时间差和jiffies计数器
  7. 12011.linux之看门狗应用开发
  8. 关于使用类成员函数作为回调的方法
  9. 宝宝三岁多了,整天自言自语,乱说一通怎么办?
  10. linux oracle 11g ora-00845,Oracle 11g ORA-00845 在Linux 下的解决方案
  11. NLPIR使用(1)
  12. mysql数据库+查询+sequence_MySQL数据库InnoDB存储引擎Log漫游
  13. Java开发实用的面试题及参考答案
  14. Qt Creator 安装 VLD
  15. iap如何初始化_STM32F4-IAP学习笔记(一)
  16. 获取Golang环境变量的三种方式
  17. 如何利用Maven查找依赖信息
  18. 计算机博士军校研究所工作,军校博士毕业怎么分配?
  19. 通信协议基础知识总结二
  20. 从搬砖工到亿万富豪,这些年他经历了什么?

热门文章

  1. 【python基础】python数据类型整理--不可变类型
  2. 基于caffe在已有模型上进行微调finetune
  3. Kuuga——转化任何 Web 页面为桌面应用的跨平台工具
  4. MATLAB,画一个全白的图
  5. 微信小程序 版本更新
  6. Python爬虫:制作一个属于自己的IP代理模块2
  7. Windows 10 关闭人脉软件
  8. 好好写简历吧!这简历一看就是包装的!!
  9. 混凝土弹塑性损伤本构模型在Abaqus中vumat子程序的实现
  10. 模电(六)放大电路分析二