bounce1d程序

这是《Unix/Linux编程实践教程》中的一个示例。其效果是在终端显示一个可以单向移动的“hello”单词,碰到边缘时,就反方向运动。同时,我们通过键盘还可以对它加以操控,如“f”键加快其运动速度,“s”降低运动速度,空格键改变运动方向,“q”表示退出。这个程序中,主要用到了curses库和linux下的信号。

其效果图如下:

curses程序

代码及注释如下:

[c]

#include<stdio.h>
#include<ncurses.h>
#include<signal.h>
#include<sys/time.h>

#define MESSAGE    "hello"
#define BLANK    "     "

//行
int row;
//列
int col;
//方向,+1或者-1
int dir;

int main()
{
//delay与ndelay代表延时,通过延时表示速度
//程序里先对ndelay进行修改
//如果按下"s",ndelay就为delay两倍
//如果按下"f",ndelay就为delay一半
int delay;
int ndelay;
//用来储存用户按下了什么键
int c;
//信号处理函数
void move_msg(int);

//curses库和屏幕的初始化
initscr();
crmode();
noecho();
clear();

//各变量的初始化
row = 10;
col = 0;
dir = 1;
delay = 2000;

//现在(10,0)出写上“hello”
move(row,col);
addstr(MESSAGE);
//绑定信号
signal(SIGALRM,move_msg);
//设定计时器
if(set_ticker(delay)==-1)    perror("set ticker");

//进入循环
while(1)
{
ndelay=0;
c = getch();
if( c == 'q') break;        //按q退出
if( c == ' ') dir = -dir;    //按空格改变方向
if( c == 'f' && delay>2 ) ndelay = delay/2;        //这两行如上所述
if( c == 's') ndelay = delay * 2 ;
if( ndelay>0 )                //通过这几行,就应该知道为何要两个delay
set_ticker(delay = ndelay );
}
endwin();
return 0;
}

//信号处理函数
void move_msg(int signum)
{
//signal(SIGALRM,move_msg);
//这里实现了一个动画效果,即hello移动了一位
//先是用空字符串把原位置抹掉
move(row,col);
addstr(BLANK);
//再把列增加(减少)一个,变成新位置
col += dir;
move(row,col);
//再把hello写在新位置上
addstr(MESSAGE);
//刷新一下,就感觉hello往右(左)动了一下
refresh();

//这几行用来判断边界
//COLS代表列的上限
if(dir==-1&&col<=0)
dir = 1;
else if(dir==1 &&col+strlen(MESSAGE)>=COLS)
dir = -1;
}

//设定计时器,用到结构体itimerval
//修改itimerval,通过setitimer更新
//it_interval、it_interval谁不为0,谁就激活
//从而实现定时功能
int set_ticker(int n_msecs)
{
struct itimerval new_timeset;
long n_sec,n_usecs;

n_sec = n_msecs/1000;
n_usecs = (n_msecs % 1000) *1000L;

new_timeset.it_interval.tv_sec=n_sec;
new_timeset.it_interval.tv_usec=n_usecs;

new_timeset.it_value.tv_sec=n_sec;
new_timeset.it_value.tv_usec=n_usecs;

return setitimer(ITIMER_REAL,&new_timeset,NULL);
}

[/c]