本文目录一览:
- 1、如何在C++中如何编写得到微妙单位的时间的代码
- 2、用visual c++ 6.0可视化编程如何编写电子时钟
- 3、用VB编程 “儿童认识钟表” 约50行
- 4、Windows程序设计编写完成一个时钟的程序
如何在C++中如何编写得到微妙单位的时间的代码
百度, ctrlc, ctrlv。。。
c++ 毫秒,微妙级计时方法
在Windows平台下,常用的计时器有两种,一种是timeGetTime多媒体计时器,它可以提供毫秒级的计时。但这个精度对很多应用场合而言还是太粗糙了。另一种是QueryPerformanceCount计数器,随系统的不同可以提供微秒级的计数。对于实时图形处理、多媒体数据流处理、或者实时系统构造的程序员,善用QueryPerformanceCount/QueryPerformanceFrequency是一项基本功。
在Intel Pentium以上级别的CPU中,有一个称为“时间戳(Time Stamp)”的部件,它以64位无符号整型数的格式,记录了自CPU上电以来所经过的时钟周期数。由于目前的CPU主频都非常高,因此这个部件可以达到纳秒级的计时精度。这个精确性是上述两种方法所无法比拟的。
在Pentium以上的CPU中,提供了一条机器指令RDTSC(Read Time Stamp Counter)来读取这个时间戳的数字,并将其保存在EDX:EAX寄存器对中。由于EDX:EAX寄存器对恰好是Win32平台下C++语言保存函数返回值的寄存器,所以我们可以把这条指令看成是一个普通的函数调用。像这样:
inline unsigned __int64 GetCycleCount()
{
__asm RDTSC
}
但是不行,因为RDTSC不被C++的内嵌汇编器直接支持,所以我们要用_emit伪指令直接嵌入该指令的机器码形式0X0F、0X31,如下:
inline unsigned __int64 GetCycleCount()
{
__asm _emit 0x0F
__asm _emit 0x31
}
以后在需要计数器的场合,可以像使用普通的Win32 API一样,调用两次GetCycleCount函数,比较两个返回值的差,像这样:
unsigned long t;
t = (unsigned long)GetCycleCount();
//Do Something time-intensive ...
t -= (unsigned long)GetCycleCount();
这个方法的优点是:
1.高精度。可以直接达到纳秒级的计时精度(在1GHz的CPU上每个时钟周期就是一纳秒),这是其他计时方法所难以企及的。
2.成本低。timeGetTime 函数需要链接多媒体库winmm.lib,QueryPerformance* 函数根据MSDN的说明,需要硬件的支持(虽然我还没有见过不支持的机器)和KERNEL库的支持,所以二者都只能在Windows平台下使用(关于DOS平台下的高精度计时问题,可以参考《图形程序开发人员指南》,里面有关于控制定时器8253的详细说明)。但RDTSC指令是一条CPU指令,凡是i386平台下Pentium以上的机器均支持,甚至没有平台的限制(我相信i386版本UNIX和Linux下这个方法同样适用,但没有条件试验),而且函数调用的开销是最小的。
3.具有和CPU主频直接对应的速率关系。一个计数相当于1/(CPU主频Hz数)秒,这样只要知道了CPU的主频,可以直接计算出时间。这和QueryPerformanceCount不同,后者需要通过QueryPerformanceFrequency获取当前计数器每秒的计数次数才能换算成时间。
这个方法的缺点是:
1.现有的C/C++编译器多数不直接支持使用RDTSC指令,需要用直接嵌入机器码的方式编程,比较麻烦。
2.数据抖动比较厉害。其实对任何计量手段而言,精度和稳定性永远是一对矛盾。如果用低精度的timeGetTime来计时,基本上每次计时的结果都是相同的;而RDTSC指令每次结果都不一样,经常有几百甚至上千的差距。这是这种方法高精度本身固有的矛盾。
下面是几个小例子,简要比较了三种计时方法的用法与精度
//Timer1.cpp 使用了RDTSC指令的Timer类//KTimer类的定义可以参见《Windows图形编程》P15
//编译行:CL Timer1.cpp /link USER32.lib
#include stdio.h
#include "KTimer.h"
main()
{
unsigned t;
KTimer timer;
timer.Start();
Sleep(1000);
t = timer.Stop();
printf("Lasting Time: %d\n",t);
}
//Timer2.cpp 使用了timeGetTime函数
//需包含mmsys.h,但由于Windows头文件错综复杂的关系
//简单包含windows.h比较偷懒:)
//编译行:CL timer2.cpp /link winmm.lib
#include windows.h
#include stdio.h
main()
{
DWORD t1, t2;
t1 = timeGetTime();
Sleep(1000);
t2 = timeGetTime();
printf("Begin Time: %u\n", t1);
printf("End Time: %u\n", t2);
printf("Lasting Time: %u\n",(t2-t1));
}
//Timer3.cpp 使用了QueryPerformanceCounter函数
//编译行:CL timer3.cpp /link KERNEl32.lib
#include windows.h
#include stdio.h
main()
{
LARGE_INTEGER t1, t2, tc;
QueryPerformanceFrequency(tc);
printf("Frequency: %u\n", tc.QuadPart);
QueryPerformanceCounter(t1);
Sleep(1000);
QueryPerformanceCounter(t2);
printf("Begin Time: %u\n", t1.QuadPart);
printf("End Time: %u\n", t2.QuadPart);
printf("Lasting Time: %u\n",( t2.QuadPart- t1.QuadPart));
}
用visual c++ 6.0可视化编程如何编写电子时钟
你好
我分长期和短期的学习来分别说一点我的建议
(1)如果你只是想通过短期时间突击来完成你这个vc6.0电子时钟的程序,而且当前时间已经不多,并且你又有一些c++的基础的情况下,我的建议是:
多找一些《《visual c++ 6.0编程实例》》的书,可以在迅雷里下载,也可以去书店找,运气好的话,可能书里面就有你做的这个例子,如果实在没有你的这个例子,那你就要首先想想你这个程序大致需要怎么做,比如说:首先确定是做个单文档的模式还是做个对话框的模式;其次是如何添加时钟的边框,如何画出指针;再次如何让表针转动等问题,有了这些问题以后,针对这些问题再去那些事例书中找对应的例子,完整的时钟例子虽然找不到,但是拆分以后的这些小步骤还是能找到的。以上就是针对你现在的基础我的一点建议。
(2)如果你以后打算从事VC的开发,下面是我的一些心得,希望能给你帮助:
1.首先是学习计算机系统的运行原理。你只有在较为深刻地了解了计算机系统的运行原理,才可能会理解代码为什么要这样写,理解一些低层的错误。在此推荐一本书,《深入了解计算机系统》,迅雷 上有下,它能让你在程序员的角度上,对计算机有个深刻的了解,很不错。
2.有了对计算机系统的运行原理的初步认识,下一步可以了解下windows的编程思想,掌握最基本的sdk编程,对于您进一步学vc好处莫大,推荐经典书籍《《window程序设计》》迅雷上也有下
3.孙鑫的《VC++从入门到精通视频教程》,vc的入门读物,比较容易理解
4.vc提高篇,推荐《深入解析Windows系统(第四版),深入剖析mfc程序的运行过程。
最后:了解点操作系统的原理对编程也是有好处的。了解一下Windows操作系统的底层原理是怎样的,虚拟内存是个什么东西,进程是什么,等等。
总得说来长期的学习,就是这几本书:
《深入了解计算机系统》《window程序设计》》《VC++深入详解》、《Windows环境下32位汇编语言程序设计》、
《Windows核心编程》、《深入解析Windows系统(第四版)》这几本书,应该是你学习编程的一个有效的过程
恩,好了,最后祝你好运!
用VB编程 “儿童认识钟表” 约50行
这么麻烦的问题你连分都不给,谁做啊?
还是自个儿好好学习吧
Windows程序设计编写完成一个时钟的程序
void CDigitalClock::DrawSingleNumber(int nNum,int nLeft)
{
switch (nNum)
{
case 0:
DrawSection1(nLeft);
DrawSection2(nLeft);
DrawSection3(nLeft);
DrawSection4(nLeft);
DrawSection5(nLeft);
DrawSection6(nLeft);
break;
case 1:
DrawSection2(nLeft);
DrawSection3(nLeft);
break;
case 2:
DrawSection1(nLeft);
DrawSection2(nLeft);
DrawSection4(nLeft);
DrawSection5(nLeft);
DrawSection7(nLeft);
break;
case 3:
DrawSection1(nLeft);
DrawSection2(nLeft);
DrawSection3(nLeft);
DrawSection4(nLeft);
DrawSection7(nLeft);
break;
case 4:
DrawSection2(nLeft);
DrawSection3(nLeft);
DrawSection6(nLeft);
DrawSection7(nLeft);
break;
case 5:
DrawSection1(nLeft);
DrawSection3(nLeft);
DrawSection4(nLeft);
DrawSection6(nLeft);
DrawSection7(nLeft);
break;
case 6:
DrawSection1(nLeft);
DrawSection3(nLeft);
DrawSection4(nLeft);
DrawSection5(nLeft);
DrawSection6(nLeft);
DrawSection7(nLeft);
break;
case 7:
DrawSection1(nLeft);
DrawSection2(nLeft);
DrawSection3(nLeft);
break;
case 8:
DrawSection1(nLeft);
DrawSection2(nLeft);
DrawSection3(nLeft);
DrawSection4(nLeft);
DrawSection5(nLeft);
DrawSection6(nLeft);
DrawSection7(nLeft);
break;
case 9:
DrawSection1(nLeft);
DrawSection3(nLeft);
DrawSection4(nLeft);
DrawSection2(nLeft);
DrawSection6(nLeft);
DrawSection7(nLeft);
break;
default:
;
}
}
void CDigitalClock::DrawSection1(int nLeft)
{
if (m_memDC.m_hDC!=NULL)
{
CPoint point[4];
point[0].x=nLeft+(int)(0.1*m_nWidth);
point[0].y=m_nYmargin;
point[1].x=nLeft+(int)(0.9*m_nWidth);
point[1].y=m_nYmargin;
point[2].x=nLeft+(int)(0.7*m_nWidth);
point[2].y=(int)(0.2*m_nWidth)+m_nYmargin;
point[3].x=nLeft+(int)(0.3*m_nWidth);
point[3].y=(int)(0.2*m_nWidth)+m_nYmargin;
CBrush br(m_crText);
CRgn rgn;
rgn.CreatePolygonRgn(point,4,ALTERNATE);
m_memDC.FillRgn(rgn,br);
br.DeleteObject();
rgn.DeleteObject();
m_memDC.MoveTo(point[0]);
m_memDC.LineTo(point[1]);
m_memDC.MoveTo(point[1]);
m_memDC.LineTo(point[2]);
m_memDC.MoveTo(point[2]);
m_memDC.LineTo(point[3]);
m_memDC.MoveTo(point[3]);
m_memDC.LineTo(point[0]);
}
}
void CDigitalClock::Draw2Dot(int nLeft)
{
if (m_memDC.m_hDC!=NULL)
{
CBrush br(m_crText);
CRect rect;
rect.SetRect(nLeft+(int)(0.3*m_nWidth),(int)(0.4*m_nWidth)+m_nYmargin,
nLeft+(int)(0.6*m_nWidth),(int)(0.7*m_nWidth)+m_nYmargin);
m_memDC.Ellipse(rect);
CRgn rgn1;
rgn1.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom);
m_memDC.FillRgn(rgn1,br);
rect.OffsetRect(0,(int)(0.8*m_nWidth)+m_nYmargin);
m_memDC.Ellipse(rect);
CRgn rgn2;
rgn2.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom);
m_memDC.FillRgn(rgn2,br);
br.DeleteObject();
rgn1.DeleteObject();
rgn2.DeleteObject();
}
}
主要代码在这~~慢看~~`