Ubuntu下codeblocks的气泡球程序(三)

来源:互联网 发布:淘宝首页psd模板下载 编辑:程序博客网 时间:2024/06/05 05:24

//***********************************************************

版本04

程序功能:实现两个球的随机运动

显示方式:实时打印球的坐标和速度

增加内容:软件延时代码

修改说明:利用随机数函数创建一个双精度比率,来设置ySpeed用以控制小球的运动方向

说明   :该程序仅在一个球的基础上增加一个球,然后对输出做一下修改

//***********************************************************

#include<stdio.h>

#include<time.h>

#include<stdlib.h>

Int main()

{

//定义边框的宽

Int TableWidth = 100;

//定义边框的高

int TableHight = 100;

//定义球的尺寸

int BallSize = 10;

//定义球纵坐标的速度

Int ySpeed01 = 5;

Int ySpeed02 = 5;

 

//使用time(0)作为随机数种子

Srand((int) time(0));

 

//定义球横坐标的速度

//这里用到了drand48()函数,用以产生一个正的浮点随机数

Int xSpeed01 =(int) ySpeed01*(drand48()-0.5)*2;

Int xSpeed02 = (int)ySpeed02*(drand48()-0.5)*2;

 

//定义球的横坐标

Int BallX01 = 1+(int)(20.0*rand()/(RAND_MAX+1.0));

Int BallX02 = 50+(int)(20.0*rand()/(RAND_MAX+1.0));

//定义球的纵坐标

Int BallY01= 50+(int)(20.0*rand()/(RAND_MAX+1.0));

Int BallY02= 1+(int)(20.0*rand()/(RAND_MAX+1.0));

 

Unsigned Int t;

Unsigned int flag =0;

While(1){

 for(t=0;t<600000000;t++);//软件延时

 

if(((BallX01-BallX02)*(Ball01-BallX02)+(BallY01-BallY02)*(BallY01-BallY02)<400))

{

     xSpeed01 = -xSpeed01;

     ySpeed01=-ySpeed01;

     xSpeed02 =-xSpeed02;

     ySpeed02 =-ySpeed02;

     flag++;

}

else

{

If(BallX01<0|| BallX01 >= TableWidth - BallSize)

  xSpeed01 =-xSpeed01;

if(BallY01<0|| BallX01 >=TableHight - BallSize)

  ySpeed01 = -ySpeed01;

If(BallX02<0|| BallX02 >= TableWidth - BallSize)

  xSpeed02 =-xSpeed02;

if(BallY02<0|| BallX02 >=TableHight - BallSize)

  ySpeed02 = -ySpeed02;

}

BallX01 +=xSpeed01;

BallY01+=ySpeed01;

BallX02 +=xSpeed02;

BallY02+=ySpeed02;

 

Printf(“Thestate of Ball01 is %d,%d,%d,%d\n”,BallX01,BallY01,xSpeed01,ySpeed01);

Printf(“Thestate of Ball02 is %d,%d,%d,%d\n”,BallX02,BallY02,xSpeed02,ySpeed02);

Printf(“flag=%d\n”,flag);

Printf(“\n”);

t=0;

}

}

 

 

 

 

 

 

以上程序存在的问题或需要考虑的问题:

1) 首先,定时打印,软件延时行不行?还有没有更好的方法实现定时打印?

2) 产生随机数函数的用法是不是正确?参考别人的程序看看

3) 程序里第二个球的横坐标越界,这是什么问题造成的,有没有想清楚?

4) 程序里第一个球在原地转圈,这种情况在andorid开发也有类似情况,是如何造成的?需要琢磨下?

5) 以上是基于C的源代码,是否可以用C++来实现呢?可以在C的基础上实现C++的算法和代码

6) 程序缺少—help,这是一个查看函数作用的帮助文件,需要添加,这个还要具体查查看,怎么加上去。

 

 

//***********************************************************

由于以上问题之间的联系是比较紧密的,可能换成C++语言,就可以解决多个问题,下面可以多多探索下

//创建时间:2014年4月23日星期三

定时器这一块可以写一个定时器函数,然后替代软件延时,但函数写完后程序是不执行计时循环的,不清楚为什么

 

下面是网友博客地址和源代码内容:

http://blog.csdn.net/onelight1997/article/details/6270180

 

linux定时器的使用

使用定时器的目的无非是为了周期性的执行某一任务,或者是到了一个指定时间去执行某一个任务。要达到这一目的,一般有两个常见的比较有效的方法。一个是用linux内部的三个定时器,另一个是用sleep, usleep函数让进程睡眠一段时间,其实,还有一个方法,那就是用gettimeofday, difftime等自己来计算时间间隔,然后时间到了就执行某一任务,但是这种方法效率低,所以不常用。

首先来看看linux操作系统为每一个进程提供的3个内部计时器。

ITIMER_REAL: 给一个指定的时间间隔,按照实际的时间来减少这个计数,当时间间隔为0的时候发出SIGALRM信号

ITIMER_VIRTUAL: 给定一个时间间隔,当进程执行的时候才减少计数,时间间隔为0的时候发出SIGVTALRM信号

ITIMER_PROF: 给定一个时间间隔,当进程执行或者是系统为进程调度的时候,减少计数,时间到了,发出SIGPROF信号,这个和ITIMER_VIRTUAL联合,常用来计算系统内核时间和用户时间。

用到的函数有:

#include<sys/time.h>
int getitimer(int which, struct itimerval *value);
int setitimer(int which, struct itimerval*newvalue, struct itimerval* oldvalue);
strcut timeval
{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
struct itimerval
{
struct timeval it_interval; /*时间间隔*/
struct timeval it_value; /*当前时间计数*/
};

it_interval用来指定每隔多长时间执行任务, it_value用来保存当前时间离执行任务还有多长时间。比如说, 你指定it_interval为2秒(微秒为0),开始的时候我们把it_value的时间也设定为2秒(微秒为0),当过了一秒, it_value就减少一个为1, 再过1秒,则it_value又减少1,变为0,这个时候发出信号(告诉用户时间到了,可以执行任务了),并且系统自动把it_value的时间重置为 it_interval的值,即2秒,再重新计数。

为了帮助你理解这个问题,我们来看一个例子:

#include<sys/time.h>

#include<stdio.h>

#include<unistd.h>

#include<signal.h>

#include<string.h>

static char msg[]= “time is running out/n”;

static int len;

// 向标准错误输出信息,告诉用户时间到了

voidprompt_info(int signo)

{

write(STDERR_FILENO,msg, len);

}

// 建立信号处理机制

voidinit_sigaction(void)

{

struct sigactiontact;

/*信号到了要执行的任务处理函数为prompt_info*/

tact.sa_handler =prompt_info;

tact.sa_flags = 0;

/*初始化信号集*/

sigemptyset(&tact.sa_mask);

/*建立信号处理机制*/

sigaction(SIGALRM,&tact, NULL);

}

void init_time()

{

struct itimervalvalue;

/*设定执行任务的时间间隔为2秒0微秒*/

value.it_value.tv_sec= 2;

value.it_value.tv_usec= 0;

/*设定初始时间计数也为2秒0微秒*/

value.it_interval= value.it_value;

/*设置计时器ITIMER_REAL*/

setitimer(ITIMER_REAL,&value, NULL);

}

int main()

{

len = strlen(msg);

init_sigaction();

init_time();

while ( 1 );

exit(0);

}

该程序的ITMER_REAL定时器,每隔2秒钟都会发送一个SIGALRM信号,当主函数接收到了这个信号之后,调用信号处理函数 prompt_info在标准错误上输出time is running out这个字符串。

对于ITIMER_VIRTUAL和ITIMER_PROF的使用方法类似,当你在setitimer里面设置的定时器为 ITIMER_VIRTUAL的时候,你把sigaction里面的SIGALRM改为SIGVTALARM, 同理,ITIMER_PROF对应SIGPROF。

不过,你可能会注意到,当你用ITIMER_VIRTUAL和ITIMER_PROF的时候,你拿一个秒表,你会发现程序输出字符串的时间间隔会不止2秒,甚至5-6秒才会输出一个,至于为什么,自己好好琢磨一下^_^

下面我们来看看用sleep以及usleep怎么实现定时执行任务。

#include<signal.h>

#include<unistd.h>

#include<string.h>

#include<stdio.h>

static char msg[]= “I received a msg./n”;

int len;

void show_msg(intsigno)

{

write(STDERR_FILENO,msg, len);

}

int main()

{

struct sigactionact;

union sigvaltsval;

act.sa_handler =show_msg;

act.sa_flags = 0;

sigemptyset(&act.sa_mask);

sigaction(50,&act, NULL);

len = strlen(msg);

while ( 1 )

{

sleep(2); /*睡眠2秒*/

/*向主进程发送信号,实际上是自己给自己发信号*/

sigqueue(getpid(),50, tsval);

}

return 0;

}

看到了吧,这个要比上面的简单多了,而且你用秒表测一下,时间很准,指定2秒到了就给你输出一个字符串。所以,如果你只做一般的定时,到了时间去执行一个任务,这种方法是最简单的。

下面我们来看看,通过自己计算时间差的方法来定时:

#include<signal.h>

#include <unistd.h>

#include<string.h>

#include<stdio.h>

#include<time.h>

static char msg[]= “I received a msg./n”;

int len;

static time_tlasttime;

void show_msg(intsigno)

{

write(STDERR_FILENO,msg, len);

}

int main()

{

struct sigactionact;

union sigvaltsval;

act.sa_handler =show_msg;

act.sa_flags = 0;

sigemptyset(&act.sa_mask);

sigaction(50,&act, NULL);

len = strlen(msg);

time(&lasttime);

while ( 1 )

{

time_t nowtime;

/*获取当前时间*/

time(&nowtime);

/*和上一次的时间做比较,如果大于等于2秒,则立刻发送信号*/

if (nowtime – lasttime >= 2)

{

/*向主进程发送信号,实际上是自己给自己发信号*/

sigqueue(getpid(),50, tsval);

lasttime =nowtime;

}

}

return 0;

}

这个和上面不同之处在于,是自己手工计算时间差的,如果你想更精确的计算时间差,你可以把 time 函数换成gettimeofday,这个可以精确到微妙。

上面介绍的几种定时方法各有千秋,在计时效率上、方法上和时间的精确度上也各有不同,采用哪种方法,就看你程序的需要

itimerval时钟的使用

#include<stdio.h>
#include<signal.h>
#include<sys/time.h>//itimerval结构体的定义

int handle_count=0;
void set_time(void)
{
struct itimerval itv;
itv.it_interval.tv_sec=10;//自动装载,之后每10秒响应一次
itv.it_interval.tv_usec=0;
itv.it_value.tv_sec=5;//第一次定时的时间
itv.it_value.tv_usec=0;
setitimer(ITIMER_REAL,&itv,NULL);
}

void alarm_handle(int sig)
{
handle_count++;
printf("have handle count is %d/n",handle_count);
}

void main(void)
{
struct itimerval itv;
signal(SIGALRM,alarm_handle);
set_time();

while(1){
getitimer(ITIMER_REAL,&itv);
printf("pass second is %d/n",(int)itv.it_value.tv_sec);
sleep(1);
}

return;
}

0 0
原创粉丝点击