wujr5 / c-and-cpp-language-learning

C和C++编程语言学习 - 2015级
67 stars 34 forks source link

计科:project1问题反馈 #45

Open wujr5 opened 8 years ago

wujr5 commented 8 years ago

对于project1的任何问题,计科的同学请在这里讨论。

Icenowy commented 8 years ago

能不能进行技术分享呢?

wujr5 commented 8 years ago

@Icenowy 当然可以。还有如果你做好的话,可以在下节课跟大家谈谈完成的思路。

Icenowy commented 8 years ago

技术分享1:在多个源文件之间共享全局变量

示例

在我的代码中,pglines, pgrows这两个变量被很多个模块共享。

其中,main.cpp初始化这两个变量,split.cpp用这两个变量来处理分屏,map.cpp用这两个变量生成地图。

做法

因为这种全局变量,定义在哪个模块都不太合适,所以我选择了增加一个源码文件,global_var.cpp,用来放整个游戏公用的全局变量。

既然增加了一个源文件,我就另外写了一个与其配套的头文件:global_var.h

global_var.h:

#ifndef _GLOBAL_VAR_H
#define _GLOBAL_VAR_H // 这两句是“引用屏障”,避免头文件被多次引用的时候出错,后面的_GLOBAL_VAR_H应该对于每一个源码文件都不同。在编写头文件的时候,一定要有这两行,除非你知道你在干什么

extern int pglines, pgrows; // 在全局变量前面加extern,代表只在这里声明这个变量,它的定义不在这里,在整个程序的另外一个地方。这里的声明,目的是提供变量的类型等信息。(如果不同地方的声明类型不同,要么编译错误,要么程序崩溃)

#endif // 与上面的#ifndef配套

global_var.cpp

#include "global_var.h" // 源文件引用对应的头文件。

int pglines, pgrows; // 这里是真正的定义,在这里才会为真正分配内存。也就是说,所有在文件里面被标记为同一名称的extern变量,都是使用同一块内存
// 注意:如果在多个不同文件里面不加static声明同样名字的全局变量,会因为名称冲突无法通过编译!函数也是哦~

然后修改Makefile,增加对global_var.cpp的编译。 (此处按下不表)

Icenowy commented 8 years ago

另外我的代码0.0.2版本已经git tag了

wujr5 commented 8 years ago

If somebody has done the step1 or step2 or even you have finished it, please contact me and I will encourage you to do the presentation to show how you design your header file. And you can also share us with the bugs or difficulty you encountered. After that, I will give you the extra scores as reward.

wujr5 commented 8 years ago

@Icenowy I have received your email, please be ready to do the presentation at this Friday. Presentation time should be limited to 5 to 10 minutes. Mind that it's better to share the design of your function prototype and the experience of development process, instead of the coding details.

At the same time, I encourage all of you to be brave to show your work, to share what you have gained with us.

When you sharing, you are gaining.

Icenowy commented 8 years ago

关于不会装Linux的同学: 如果你们的机器CPU支持虚拟化技术(Intel的话,i3/i5/i7应该都支持,旧的core2有一部分支持;AMD的话我暂时不知道Orz),可以使用我做的AOSC Click-To-Run包(包括VirtualBox虚拟机和AOSC OS Mate系统的虚拟磁盘) 解压需要20GB空间,为了保证系统运行,需要硬盘上有50GB剩余空间 (如果不足50GB,虚拟机可能会在占用满硬盘之后报错) 下载地址: https://repo.anthonos.org/misc/AOSC-Click-To-Run-MATE.exe (原始地址,不建议使用) http://mirrors.ustc.edu.cn/anthon/misc/AOSC-Click-To-Run-MATE.exe (USTC地址,在校园网下载可以达到2MB/s以上,最高30MB/s) 另外ustc的服务器做了反迅雷处理,由于迅雷自动寻找镜像站的特性,会导致任何地址用迅雷下载的文件都可能出现问题,切记切记!

yyh15336238 commented 8 years ago

为了让蛇自己动起来,花了不少时间,弱弱的在这里说一下。

#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

加了这几个头文件,实际上能让蛇自己动就已经实现了调整游戏运行速度。 但弱弱的我除了time.h其他都不懂,目的就是为了调用kbhit()函数来检测键盘是否有输入。但这个是windows上的,要在Linux上用,我在网上弄了些“手段”,包括那些头文件还有

int kbhit (void)   {  
  struct termios oldt, newt;  
  int ch;  
  int oldf;  

  tcgetattr(STDIN_FILENO, &oldt);  
  newt = oldt;  
  newt.c_lflag &= ~(ICANON | ECHO);  
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);  

  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);  
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);  
  ch = getchar();  
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);  

  fcntl(STDIN_FILENO, F_SETFL, oldf);  

  if(ch != EOF)  {  
    ungetc(ch, stdin);  
    return 1;  
  }  
  return 0;  
}

(其实我看不懂),然后再.h中讲一下,kbhit()就可以用了。在scanKeyboard里稍作修改就可以了 加一些内容:

long start;
int gamespeed = 130000;//这里和Windows上不同,不是1000为一秒,若打1000很快就完了
start  =  clock();//开始计时

for ( ; ; )  {
  int finish = clock();
  if  ( ( finish - start > gamespeed ) || ( kbhit() )  ) {  //要么超时,要么键入,唯二方法跳出循环
    if  ( !( finish - start > gamespeed ) )  {
      in = getchar();//还是原来的配方...
      return in;
    } else {
     //保持原运动方向状态,这个可以在switch里保存状态
     //比如上一次是向上,return ‘W’;
    }
  }
}
Icenowy commented 8 years ago

有个常数好像叫CLOCK_PER_SECOND还是类似的,控制time.h的time()的时间流速

---- Ryan编写 ----

为了让蛇自己动起来,花了不少时间,弱弱的在这里说一下。

include

include

include

include <sys/ioctl.h>加了这几个头文件,实际上能让蛇自己动就已经实现了调整游戏运行速度。

但弱弱的我除了time.h其他都不懂,目的就是为了调用kbhit()函数来检测键盘是否有输入。但这个是windows上的,要在Linux上用,我在网上弄了些“手段”,包括那些头文件还有 int kbhit(void) { struct termios oldt, newt; int ch; int oldf; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); oldf = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); fcntl(STDIN_FILENO, F_SETFL, oldf); if(ch != EOF) { ungetc(ch, stdin); return 1; } return 0; }(其实我看不懂),然后再.h中讲一下,kbhit()就可以用了。在scanKeyboard里稍作修改就可以了 加一些内容:long start; int gamespeed = 130000;//这里和Windows上不同,不是1000为一秒,若打1000很快就完了 start = clock();//开始计时 for (;;) { int finish=clock(); if ((finish-start>gamespeed) || (kbhit()) ){//要么超时,要么键入,唯二方法跳出循环 if (!(finish-start>gamespeed)) { in=getchar();//还是原来的配方... return in; } else { //保持原运动方向状态,这个可以在switch里保存状态 //比如上一次是向上,return ‘W’; } } }


Reply to this email directly or view it on GitHub: https://github.com/wujr5/c-and-cpp-language-learning/issues/45#issuecomment-167402683

Icenowy commented 8 years ago

另外我解释一下这个kbhit函数,它把stdin设置成了非阻塞模式(即如果没有输入,不等到,直接返回错误),然后读stdin,读不出东西就是没有hit,读得出就是有hit

---- Ryan编写 ----

为了让蛇自己动起来,花了不少时间,弱弱的在这里说一下。

include

include

include

include <sys/ioctl.h>加了这几个头文件,实际上能让蛇自己动就已经实现了调整游戏运行速度。

但弱弱的我除了time.h其他都不懂,目的就是为了调用kbhit()函数来检测键盘是否有输入。但这个是windows上的,要在Linux上用,我在网上弄了些“手段”,包括那些头文件还有 int kbhit(void) { struct termios oldt, newt; int ch; int oldf; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); oldf = fcntl(STDIN_FILENO, F_GETFL, 0); fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); ch = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldt); fcntl(STDIN_FILENO, F_SETFL, oldf); if(ch != EOF) { ungetc(ch, stdin); return 1; } return 0; }(其实我看不懂),然后再.h中讲一下,kbhit()就可以用了。在scanKeyboard里稍作修改就可以了 加一些内容:long start; int gamespeed = 130000;//这里和Windows上不同,不是1000为一秒,若打1000很快就完了 start = clock();//开始计时 for (;;) { int finish=clock(); if ((finish-start>gamespeed) || (kbhit()) ){//要么超时,要么键入,唯二方法跳出循环 if (!(finish-start>gamespeed)) { in=getchar();//还是原来的配方... return in; } else { //保持原运动方向状态,这个可以在switch里保存状态 //比如上一次是向上,return ‘W’; } } }


Reply to this email directly or view it on GitHub: https://github.com/wujr5/c-and-cpp-language-learning/issues/45#issuecomment-167402683