user-0 提问: C语言定时器的使用  计算质点运动的位移

回复:
user: user-0
content: 我还是用的我那个方法，把定时器放在V S中设置，不断给程序发时间t。编写的程序不用C了，改用C++,不知道为什么scanf不能实现我想要的功能，只能用c++中的输入函数

user: user-1
content: 参考下面：#pragma comment(lib,"user32") #include <stdio.h> #include <time.h> #include <sys/timeb.h> #include <windows.h> char datestr[16]; char timestr[16]; char mss[4]; void log(char *s) {     struct tm *now;     struct timeb tb;      ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,s); } VOID CALLBACK myTimerProc1(   HWND hwnd, // handle of window for timer messages   UINT uMsg, // WM_TIMER message   UINT idEvent, // timer identifier   DWORD dwTime // current system time ) {  log("In myTimerProc1\n"); } VOID CALLBACK myTimerProc2(   HWND hwnd, // handle of window for timer messages   UINT uMsg, // WM_TIMER message   UINT idEvent, // timer identifier   DWORD dwTime // current system time ) {  log("In myTimerProc2\n"); } int main() {     int i;     MSG msg;      SetTimer(NULL,0,1000,myTimerProc1);     SetTimer(NULL,0,2000,myTimerProc2);     for (i=0;i<20;i++) {         Sleep(500);         log("In main\n");         if (GetMessage(&msg,NULL,0,0)) {             TranslateMessage(&msg);             DispatchMessage(&msg);         }      }     return 0; } //2012-07-26 17:29:06.375 In main //2012-07-26 17:29:06.875 In myTimerProc1 //2012-07-26 17:29:07.375 In main //2012-07-26 17:29:07.875 In myTimerProc2 //2012-07-26 17:29:08.375 In main //2012-07-26 17:29:08.375 In myTimerProc1 //2012-07-26 17:29:08.875 In main //2012-07-26 17:29:08.875 In myTimerProc1 //2012-07-26 17:29:09.375 In main //2012-07-26 17:29:09.890 In myTimerProc2 //2012-07-26 17:29:10.390 In main //2012-07-26 17:29:10.390 In myTimerProc1 //2012-07-26 17:29:10.890 In main //2012-07-26 17:29:10.890 In myTimerProc1 //2012-07-26 17:29:11.390 In main //2012-07-26 17:29:11.890 In myTimerProc2 //2012-07-26 17:29:12.390 In main //2012-07-26 17:29:12.390 In myTimerProc1 //2012-07-26 17:29:12.890 In main //2012-07-26 17:29:12.890 In myTimerProc1 //2012-07-26 17:29:13.390 In main //2012-07-26 17:29:13.890 In myTimerProc2 //2012-07-26 17:29:14.390 In main //2012-07-26 17:29:14.390 In myTimerProc1 //2012-07-26 17:29:14.890 In main //2012-07-26 17:29:14.890 In myTimerProc1 //2012-07-26 17:29:15.390 In main //2012-07-26 17:29:15.890 In myTimerProc2 //2012-07-26 17:29:16.390 In main //2012-07-26 17:29:16.390 In myTimerProc1 //2012-07-26 17:29:16.890 In main //2012-07-26 17:29:16.890 In myTimerProc1 //2012-07-26 17:29:17.390 In main //2012-07-26 17:29:17.890 In myTimerProc2 //2012-07-26 17:29:18.390 In main //2012-07-26 17:29:18.390 In myTimerProc1 //2012-07-26 17:29:18.890 In main //2012-07-26 17:29:18.890 In myTimerProc1 //2012-07-26 17:29:19.390 In main //2012-07-26 17:29:19.890 In myTimerProc2  和下面：#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h>     #include <process.h>     #define  MYVOID             void #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define ARRSIZE(x) (sizeof(x)/sizeof(x[0])) #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; char logstr[16000]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;       if (NULL==pszFmt||0==pszFmt[0]) return;     if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }             flog=fopen(logfilename1,"a");             if (NULL==flog) return;         }         fclose(flog);     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int No_Loop=0; MYVOID testThread(void *pcn) {     int n,i;      n=(int)pcn;     i=0;     while (1) {         sleep_ms(1000);         Log("in testThread %d:i==%ds\n",n,++i);         if (i>=5) No_Loop=1;     } } int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL);     pthread_t threads[1];     int threadsN;     int rc; #endif     Log("=========BEGIN==================\n"); #ifdef WIN32     _beginthread((void(__cdecl *)(void *))testThread,0,(void *)1); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,testThread,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif     i=0;     while (1) {         sleep_ms(100);         Log("in main:i==%d\n",++i);         if (No_Loop==1) break;//     }     Log("=========END====================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //2012-06-14 16:27:21.500 =========BEGIN================== //2012-06-14 16:27:21.609 in main:i==1 //2012-06-14 16:27:21.718 in main:i==2 //2012-06-14 16:27:21.828 in main:i==3 //2012-06-14 16:27:21.937 in main:i==4 //2012-06-14 16:27:22.046 in main:i==5 //2012-06-14 16:27:22.156 in main:i==6 //2012-06-14 16:27:22.265 in main:i==7 //2012-06-14 16:27:22.375 in main:i==8 //2012-06-14 16:27:22.484 in main:i==9 //2012-06-14 16:27:22.500 in testThread 1:i==1s //2012-06-14 16:27:22.593 in main:i==10 //2012-06-14 16:27:22.703 in main:i==11 //2012-06-14 16:27:22.812 in main:i==12 //2012-06-14 16:27:22.921 in main:i==13 //2012-06-14 16:27:23.031 in main:i==14 //2012-06-14 16:27:23.140 in main:i==15 //2012-06-14 16:27:23.250 in main:i==16 //2012-06-14 16:27:23.359 in main:i==17 //2012-06-14 16:27:23.468 in main:i==18 //2012-06-14 16:27:23.500 in testThread 1:i==2s //2012-06-14 16:27:23.578 in main:i==19 //2012-06-14 16:27:23.687 in main:i==20 //2012-06-14 16:27:23.796 in main:i==21 //2012-06-14 16:27:23.906 in main:i==22 //2012-06-14 16:27:24.015 in main:i==23 //2012-06-14 16:27:24.125 in main:i==24 //2012-06-14 16:27:24.234 in main:i==25 //2012-06-14 16:27:24.343 in main:i==26 //2012-06-14 16:27:24.453 in main:i==27 //2012-06-14 16:27:24.500 in testThread 1:i==3s //2012-06-14 16:27:24.562 in main:i==28 //2012-06-14 16:27:24.671 in main:i==29 //2012-06-14 16:27:24.781 in main:i==30 //2012-06-14 16:27:24.890 in main:i==31 //2012-06-14 16:27:25.000 in main:i==32 //2012-06-14 16:27:25.109 in main:i==33 //2012-06-14 16:27:25.218 in main:i==34 //2012-06-14 16:27:25.328 in main:i==35 //2012-06-14 16:27:25.437 in main:i==36 //2012-06-14 16:27:25.500 in testThread 1:i==4s //2012-06-14 16:27:25.546 in main:i==37 //2012-06-14 16:27:25.656 in main:i==38 //2012-06-14 16:27:25.765 in main:i==39 //2012-06-14 16:27:25.875 in main:i==40 //2012-06-14 16:27:25.984 in main:i==41 //2012-06-14 16:27:26.093 in main:i==42 //2012-06-14 16:27:26.203 in main:i==43 //2012-06-14 16:27:26.312 in main:i==44 //2012-06-14 16:27:26.421 in main:i==45 //2012-06-14 16:27:26.500 in testThread 1:i==5s //2012-06-14 16:27:26.531 in main:i==46 //2012-06-14 16:27:26.531 =========END====================

user: user-0
content: 我在VS2012开发环境下做了一个IDE，该IDE内核是MinGW编译器，也就是我在VS平台下运行出来另外一个编译器的IDE。用过MinGW的人应该知道，需要在CMD窗口中输入命令开关，例如编译命令：gcc -o test test.c。我使用了匿名管道来实现与后台MinGW（其实就是CMD）进程的通信，将编译、调试的命令发送过去，然后通过输出管道ReadFile，然后将读出的结果显示在IDE中就可以了。      现在我想在这个IDE下编写一段可以模拟质点运动的。首先，我需要给它输入一个字符串数组，比如01 06 1.00 1.00 3.00 3.00 0.00 2.00，01是命令标识，06代表我后面传了6个数，后面分别是x1,y1,x2,y2,a,v。通过字符串处理的子函数char * mid(char *dst,char *src, int n,int m)，我可以提取这个数组中的坐标值和加速度和速度，接下来我要进行质点运动的模拟。由于时间t是位置的，这里便需要在循环中输入时间t，得到输出，直到质点到达目标点。我写了一段C程序如下： #include <string.h> #include<stdlib.h>  #include<stdio.h> #include<math.h>  typedef struct { 	float x; 	float y;  }PointStruct;  PointStruct* PointList; float a,v,X,Y;  float r[20],r1[20],T[20]; float Tan[20],Sin[20],Cos[20]; int t; int main() {     char * mid(char *dst,char *src, int n,int m);         char strData[100]={"0"};     scanf("%s",strData);//输入字符串     char destData0[100]={"0"};     char destData1[100]={"0"};     char destData2[100]={"0"};     int d=atoi(mid(destData0,strData,2,3));     int p=(d-2)/2;     a=atof(mid(destData1,strData,4,(6+p*10)));     v=atof(mid(destData2,strData,4,(11+p*10)));      PointList=(PointStruct *)calloc(p,sizeof(PointStruct));     int j;     for(j=0;j<p;j++)     { 	 char destData3[35]={"0"};          char destData4[35]={"0"};          PointList[j].x=atof(mid(destData2,strData,4,(2*j+1)*5+1));          PointList[j].y=atof(mid(destData3,strData,4,(2*j+2)*5+1));     }       int k;     for(k=0;k<p;k++)     { 	 Tan[k]=(PointList[k+1].y-PointList[k].y)/(PointList[k+1].x-PointList[k].x);          r1[k]=atan(Tan[k]);          Sin[k]=sin(r[k]);          r[k]=sin(r1[k]);          Cos[k]=cos(r[k]);          T[k]=(PointList[k+1].y-PointList[k].y)/(v*Sin[k]);     }              int m,n;     for(m=0;m<p-1;m++)    {       for(n=1;n<=T[m]/0.1;n++)      {             scanf("%d",&t);//输入时间              X=v*0.1*t+PointList[0].x;              Y=v*0.1*t+PointList[0].y;               printf("%.2f",X);              printf("%.2f",Y);              printf("%.2f",r[m]);              printf("%.2f",a);              printf("%.2f",v);      }    }   }  char * mid(char *dst,char *src, int n,int m) {       char *p = src;       char *q = dst;       int len = strlen(src);       if(n>len)      n = len-m;    /*从第m个到最后*/       if(m<0)      m=0;    /*从第一个开始*/       if(m>len)      return NULL;       p += m;       while(n--)     *(q++) = *(p++);       *(q++)='\0';      return dst;   }        该程序在编译器IDE中编译成功后，运行，此时需要输入字符串数组，则把01 06 1.00 1.00 3.00 3.00 0.00 2.00传给运行中的程序，传的方式和MinGW命令的传送方式一样，也是在VS中向管道中写命令，将该数组作为字符串传到管道中。接下来应该输入时间，由于要模拟质点运动，我在VS设置了一个定时器，每隔一定时间是t++，并将该时间同样输入管道中，程序获得时间t后将输出，这样就能按照定时器设置的时间间隔输出坐标值，角度，加速度和速度。       这是我的整理思路，C程序在MinGW中运行没问题，输入字符串后，在输入时间t，就可以不断得到输出。。但是当把该程序放到编译器IDE（MinGW内核）中便没有我想的这么简单了，字符串可以输入，但scanf("%d",t)却不起作用，也就是没办法由定时器不断将给C程序输入时间t从而得到输出值。。。而且在运行过程中，明显感觉编译器IDE很容易崩溃。。。。不知道为什么啊，调试了好多天了，程序太大也不好给大家看，大神们先评判下我的思路哪里出了问题。。。然后，大家有没有用管道调用MinGW的经验，有可能是什么问题导致IDE崩溃？管道在使用的时候会导致什么问题？

user: user-0
content: 写了一段简单的累加程序，需要用定时器不停的给输入下一个值，一个C++ 的，一个C的，没想到C++的就能按照预想的进行累加，C的就不行         是因为C程序里面的scanf不能这样用吗？还是因为平台是C++语言，有冲突什么的？

user: user-0
content: 我就是想问一下，C语言里面有没有自己写的时钟中断函数？不是基于单片机的

user: user-1
content: 直线段：起始点坐标(x1,y1)和终止点坐标(x2,y2) 上的每一点的坐标可用公式 Xa=X1+a*(X2-X1) Ya=Y1+a*(Y2-Y1) 表示，其中a在0..1之间

user: user-1
content: 为什么不用 BOOL LineDDA(   int nXStart,             // x-coordinate of line's starting point   int nYStart,             // y-coordinate of line's starting point   int nXEnd,               // x-coordinate of line's ending point   int nYEnd,               // y-coordinate of line's ending point   LINEDDAPROC lpLineFunc,  // pointer to callback function   LPARAM lpData            // pointer to application-defined data ); 呢？

user: user-0
content: 引用 7 楼 zhao4zhong1 的回复:你在回调函数中通过延时或计算，可以选择发或不发啊。  这个是VC里面的函数吗？我要用C语言来编

user: user-1
content: 你在回调函数中通过延时或计算，可以选择发或不发啊。

user: user-0
content: 引用 5 楼 zhao4zhong1 的回复:为什么不用 BOOL LineDDA(   int nXStart,             // x-coordinate of line's starting point   int nYStart,             // y-coordinate of line's starting point   int nXEnd,               // x-coordinate of line's ending point   int nYEnd,               // y-coordinate of line's ending point   LINEDDAPROC lpLineFunc,  // pointer to callback function   LPARAM lpData            // pointer to application-defined data ); 呢？      查了一下LineDDA，它的功能就是计算出连接两点的线段上的每一个屏幕像素的坐标，这两个点的坐标已经在函数的前四个参数中给出，每计算出一个坐标，该函数就会调用第五个参数所指的回调函数，我们可以在回调函数中完成一些简单的操作，以实现动画效果。。       但是我并不是想在这两点的直线上完成什么操作，而是模拟质点运动，每隔时间 t 质点运动到哪里了，我会把这个时刻的坐标发给仿真环境那里，控制质点的运动。后面仿真的部分不需要我做，我的任务是发给他当前质点运动的坐标，以时间 t 为间隔的发

user: user-2
content: 你可以使用 alarm（）  ualarm（）  的信号机制。 在SIGALRM 信号捕捉函数中处理你的逻辑

user: user-0
content: 到处都看到C++里面的写法，比如SetTimer（），TimeSetEvent（），但就是查不到标准C里面是怎么做的。我希望可以像SetTimer，每隔一定时间就可以得到这个时间间隔，并进行对位移计算

user: user-0
content: 程序开始运行时定时器一直工作，知道得到的坐标值是终止点坐标，停止

user: user-0
content: 引用 1 楼 zhouqinghe24 的回复:你可以使用 alarm（）  ualarm（）  的信号机制。 在SIGALRM 信号捕捉函数中处理你的逻辑你好  能通过一小段代码说详细点吗