问题描述:
我想用VC编一个小程序 作用是将一条已知端点的线段均分 求出其分点坐标(包括端点)(端点坐标 份数 需饥蔽仿自己输入)C++程序已经写好了(可以运行) 但要将其可视化 有对烂纤话框的那种 不只是在命令提示符里那种 我不大会并橡 请指教 怎么编写 大体步骤也可以 谢谢
解析:
vc的代码是:
void CLineDlg::OnPaint() //画一条直线
{
CDC *pDC=GetDC()
CPen newpen(PS_DASHDOTDOT,2,(COLORREF) 0)
CPen *oldpen=pDC->SelectObject(&newpen)
pDC->MoveTo(x1,y1)//这就是已知直线的起始端点坐标20,20
pDC->LineTo(x2,y2)//终点的坐标100,20
pDC->SelectObject(oldpen)
}
void CLineDlg::OnButton1()
{
CString str
str.Format("中点的坐标是: %d %d",(x1+x2)/2,(y1+y2)/2)
GetDlgItem(IDC_EDIT1)->SetWindowText(str)
}
这其中的x1,x2,y1,y2都是一个整数值,是一个全局变量
在构造函数当中要初始化,也就是要赋值。
您好!虽然有点多,但对您总是有好处的,看得越多,好处也越多。呵呵
C++语言相对于C语言来说引入了两个大的新东西,一个就是面向对象(具体来将就是类
),另外就是模板技术(模板编程或者叫泛型编程是进来非常流行的技术,在C#中虽然还
没有对泛型编程的支持,但是相信在将来也一定会加入这一功能),模板是C++中比较复
杂的部分,但是作为一个真正的C++程序员,这部分很重要。尤其是对C++标准程序库
的掌握尤为重要。
刚开始的时候千万不要直扑VC中的各种向导和设计器。因为依赖开发环境生成的很多代码
会把我们搞糊涂,也不利于我们学习C++语言本身。我的建议就是生成一个空的控制台工
程,然后自己向里面添加文件。
如下就是一个简单的控制台程序:
//robindy/list.cpp
#i nclude
#i nclude
using namespace std
int main()
{
list coll
for(char c = 'a'c <= 'z'++c)
{
coll.push_back(c)
}
list::const_iterator pos
for(pos = coll.begin()pos != coll.end()++pos)
{
cout <<*pos <<' '
}
cout <<endl
return 0
}
对using namespace std的解释:
所谓namespace,是指标识符的各种可见范围。C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:
1、直接指定标识符。例如std::ostream而不是ostream。完整语句如下:
std::cout <<std::hex <<3.4 <<std::endl
2、使用using关键字。
using std::cout
using std::endl
以上程序可以写成
cout <<std::hex <<3.4 <<endl
3、最方便的就是使用using namespace std这样命名空间std内定义的所有标识符都有效(曝光)。就好像它们被声明为全带行局变量一样。那么以上语句可以如下写:
cout <<hex <<3.4 <<endl
这段程序用到了标准模板库,在屏幕上打印字符a~z,其中main函数的标记式只有两种是被
C++标准委员会接受的,只有以下两种写法是符合C++标准的,是可移植的。即:
int main()
{
}
和
int main(int argc, char* argv[])
{
}
C++在main()的末尾定义了一个隐式的return 0但是在VC中必须显式的写出return语句。
在BCB中可以不写return而编译通过。
这段程序中用到了STL中的容器:链表。先是向链表中插入26个字母,然后从遍历链表,输
出字符。
我不建议初学者一开始就从模板库入手,但是我建议应该逐渐地有意识地学习模板库。如
我们应该熟悉cout和cin的用梁者法(位于iostream),而减少使用老式的C函数库中printf和sc
anf等。
从控制台入手的好处就是避免我们理解VC中向导等工具生成的其他代码,整个程序的流程
很清楚。新手学习VC的一大难点就是搞不清楚整个程序的流程(从那条语句开始执行,然后
从那条语句退出。MFC做了太多封装,掩盖了事实的真相,^_^)。通过控制台我们可以很快
地学习C++语言中的很多新特性。如类的封装、继承和多态等。通过这个时期的学习,要
能够掌握三个东西: C++关键字、语法(重点是和面向对象有关的,以及模板)、C++
标准程序库(知道怎么使用即可,要彻底掌握需要很多时间和精力)。至于与界面有关的
东东(MFC中很大一部分是与界面相关的类,所以我认为MFC很臃肿而无聊!回头看过以前
用MFC写的程序,有一种“垃圾”的感觉。)
自己做个测试:
写一个控制台程序,在其中体现出类的继承,函数重载,动态多态(通过虚函数实现),
数据封装,C++标准库的运用。
如果你能够轻松搞定,恭喜你,你已经通过C++语言关了。不过C++实在是一个复杂的
东东,其中有各种千奇百怪的语法现象,如果没有三、五年的功力,千万橡行薯不要说自己懂C+
+。^_^。
推荐书籍《Thinking in C++》(有精力的话,可以直接读原版)
《Essential C++》
本来我计划继续说说如何来进入C++世界的,但是琢磨了一下,觉得还是要先解决一个问
题:为什么要学习C++?我觉得在软件开发这个行当了里除了为了生计外,学习新东西都
是应该以兴趣为导向的。所以撇开我个人对C++的偏爱,我想为你树立起学习C++的信
心和兴趣。当初我对自己学习C++的第一个忠告就是:不能半途而废!起初是兴趣驱动,
后来则是生计所需,最后还是回归到了兴趣。毕竟我从中得到了乐趣,这就足够了。在学
一个新东西前,解决动机问题很重要。就如同杀人一样,如果只是突然兴起,那么等尝试
了以后,是没有成就感的。革命先烈们为我们作出了很好的榜样,就算我们在学习C++的
道路上遇到了太多困惑和痛苦,但是我们毕竟为自己的信念做了努力,我们知道自己在
做什么,知道自己在追求什么。
C++适合做什么样的开发?
C++是一门广泛用于工业软件研发的大型语言。具有很高的复杂性和解决问题的能力。C
++不仅在开发上极具价值,同时在学术界也就有很高的价值。有关C++的文章应该可以
用浩如烟海来形容了吧。C++的世界级经典书籍也是数不胜数。然而,目前开发语言是如
此地繁荣,就连微软也在推出了新的开发语言C#。一个不可否认的现实是,在低阶程序设
计领域,C++挤压着C同时也在承受着C的强烈反d,前段时间看了据说是微软 *** 作系统源代
码的东东,其中很多还是C语言。而在高阶程序设计领域,Java和C#正在不断蚕食着C++的
地盘。也许Java和C#的狂潮终将迫使C++回归本位— 回到它有着根本性优势的开发领域:
低级系统程序设计、高级大规模高性能应用设计、嵌入式程序设计、通用程序设计以及数
值科学计算等。果真如此,我认为这未尝不是一件好事。电力系统软件所要求的高性能和
大规模数值计算正是C++所擅长的。就我所接触的南瑞和鲁能,很多涉及到电力系统计算
的软件如PAS等,都是用C++来开发的。在电力系统软件开发这块阵地,C++大有用武之
地。C++吸引如此之多的智力投入,以至于这个领域的优秀作品,包括重量级的软件产品、
程序库以及书籍等,数不胜数。在C++之父Bjarne Stroustrup的个人主页上,有一页
列出了一些(全部或大部分)使用C++编写的系统、应用程序和库。
下面是一些例子(摘自荣耀网站):
o Adobe Systems:所有主要应用程序都使用C++开发而成,比如Photoshop &ImageReady
、Illustrator和Acrobat等。
o Maya:知道“蜘蛛人”、“指环王”的电脑特技是使用什么软件做出来的吗?没错,就
是Maya。
o Amazon.com:使用C++开发大型电子商务软件。
o Apple:部分重要“零件”采用C++编写而成。
o AT&T:美国最大的电讯技术提供商,主要产品采用C++开发。
o Google:Web搜索引擎采用C++编写。
o IBM:OS/400。
o Microsoft:以下产品主要采用C++(Visual C++)编写:
o Windows XP Windows NT:NT4、2000 Windows 9x:95、98、Me Microsoft Office:Wo
rd、Excel、Access、PowerPoint、Outlook Internet Explorer,包括Outlook Express
Visual Studio:Visual C++、Visual Basic、Visual FoxPro .NET Framework类库采用C
#编写,但C#编译器自身则使用C++编写而成。Exchange SQL Server FrontPage Project
所有游戏......
o KDE:K Desktop Environment(Linux)。
o Symbian OS:最流行的蜂窝电话OS之一。
C++源于C语言,还记得很久以前学习C语言的时光(那是一段快乐而充实的时光),可是
现在学习C++,并不是在C的基础上加上了类而已,如果这样认为,我们是耍不好C++的
。因此,C++绝不是C的升级或扩充,我们应该把C++当作一门新语言来学习(C++之
父Bjarne Stroustrup语)。
写程序首先希望是程序能正确执行,其次是效率能够被接受,再次就是易于维护。C++是
一个难学易用的语言。C++提供了太多可选择的东西,而且使用使用C++来写程序可以
有四种思考模式:基于过程、基于对象、面向对象和泛型。我们使用一种语言来写程序,
并不意味着就是使用语言本身,换句话说,我们更多的时候是使用程序库在写程序。比如
MFC、STL、ATL、VCL等等。其中要使用C++来写出结构优美、性能卓越、代码简洁、易于
维护的代码,首推C++标准程序库。STL对效率做了严格的要求,而且使用STL写出来的程
序简洁美观(前段时间我特意贴了一个要求对若干整数进行排序的帖子,其实目的就是用来
展示STL的简洁优雅)。一旦习惯使用泛型思维来考虑问题,我们能够充分体会到模板带来的美!
对于数值计算来说,C++标准程序库可以充分满足现代化服务和商业计算对数据、信息的即
时回应的要求。
我觉得学好一门语言最重要的就是实践。也就是多“写”!“工程经验之积累”对已具有
一段开发时间的程序员而言,非常重要!只有在不断的积累中,我们才能渐渐体会到C++
语言中的一些背后的东西。对于这点,没有大量程序代码写作经验的菜鸟,也可以借助《
Effective C++》先攒一些经验值。《Effective C++》是一本好书!。Meyers的书绝对值
得一读,Meyers可以说当今C++社群中数一数二的技术专家。
推荐网站:
www.royaloo.com
以下文字应该是去年所涂鸦而成,主要是关于动态内存分配的,在这里将其重新看了看
,觉得还是写得太浅薄了。因为内存是程序运行的“运动场”,对场地的了解程度会直接
影响到我们程序运行的流畅度和稳定性。
C++提供了 *** 作符new来在堆上分配内存, *** 作符delete来释放内存。有些情况下,我
们需要对内存的分配和释放进行更好的控制。许多程序创建和释放一些重要类的大量的对
象,如tree nodes,linked lists links,points,lines,messages,etc.使用通用的内存分
配器如new和delete来进行这些对象的分配和释放有时将支配程序的运行时间和内存需求。
两方面的因素:通用内存分配 *** 作的运行和空间的耗费以及不同对象大小引起的内存碎片
。类使用定制的内存分配器将加快模拟器、编译器和类似程序的执行速度。
例外一种需要更好的内存控制的情况是:需要在有限资源的情况下长时间不间断运行
的程序。实时系统经常需要用最少的耗费来获取有保证的可预期的内存。这也就导致了更
好的内存控制的需要。一般来说,这些程序都避免使用动态的内存分配,而使用特殊目的
的内存分配器来管理有限资源。
此外,还有一些情况下由于硬件或系统的要求,需要将对象放在指定的内存位置。这也
需要进行定制的内存管理(通过重载new来加以实现)。
在C++ Release 2.0中,为了满足以上需求,内存管理机制做了相应的修改。主要是引
进了operator new [] 和 operator delete []。
new *** 作符的作用范围(Scope for operator new Functions)
*** 作符(Operator) 范围(Scope)
::operator new Global
class-name::operator new Class
operator new的第一个参数必须是类型size_t(在STDDEF.H中定义的类型),返回类型
为void *。
当分配内建(built-in)类型的对象、未包含用户自定义的new *** 作符函数的类对象、任何
类型的数组时,使用全局new *** 作符函数。当在类中自定义new *** 作符时,分配该类对象的
内存时,调用该类的new *** 作符。如下:
#i nclude
#i nclude
class Blanks
{
public:
Blanks(){}
void *operator new( size_t stAllocateBlock, char chInit )
}
void *Blanks::operator new( size_t stAllocateBlock, char chInit )
{
void *pvTemp = malloc( stAllocateBlock )
if( pvTemp != 0 )
memset( pvTemp, chInit, stAllocateBlock )
return pvTemp
}
int main()
{
Blanks *a5 = new( 0xa5 ) Blanks//创建对象Blanks,并且初试化为0xa5
return a5 != 0
}
new *** 作符可以重载,而delete却不行。因为等到需要释放的时候,我们所能得到的就
是一个指针。而且该指针可能不是原先的对象类型指针(有可能进行了类型转换)。实际
上,当使用new获得一个指向一片内存的指针时,在该片内存前有一个指示器(indicator)
,记录实际分配的内存数量。当调用delete时,可以获知需要释放的内存大小。
数组的释放(Deallocating Arrays):
void f( )
{
X* p1 = new X[10]
//...
delete [] X
}
为什么不使用delete [10] X来释放内存?Bjarne Stroustrup称这种做法容易导致错
误,而将记录元素个数的任务放在delete的实现中了。
至于为什么C++中未内建垃圾收集器(Garbage Collection)的原因,看《C++语言的设
计和演化》(En) Bjarne Stroustrup 机械工业出版社(俗称:D&E)可以得到答案。
此外,C++标准库中提供了一种智能型指针auto_ptr,这种指针可以帮助我们防止“被
异常抛出时发生资源泄漏”。但是缺点是该智能型指针不能指向数组,因为其内部释放内
存是通过delete而非delete [] 来进行的。所以,只能使用其来指向一个单个对象。
模板部分是C++中比较难的部分,也是C++的魅力所在。以下文字是我以前看过的,具
体出处不清楚了。今天稍微整理了一下,作为模板介绍的一个单元。
为什么要使用模板
对于除类型之外,其余都相同的函数(譬如quicksort),我们一般有3种解决办法。
1、针对每个不同的类型重复地编写函数实体(C语言的做法):
int* quicksort(int a[]) {... }
double* quicksort(double a[]) {... }
…
2、使用Object(Java的做法)或者void*
缺点有两个
效率问题方面也有问题
类型检查问题
3、使用宏预处理机制
缺点:只是愚蠢的文本替换,而且也不会考虑作用域和类型安全。
然而,应用模板却可以避免这些缺点,我们可以编写:
template
T* quicksort(T a[]) {... }
优点:
代码简洁优雅,所有参数类型都以T来代替,真正实现了类型无关性。
更好的类型安全性,所有的类型检查都是在编译期进行,而且避免使
用指针。
不存在继承,效率高。(1)没有虚函数;(2)所有的一切工作都是
在编译期完成,大大提高运行效率。
目的:告诉编译器如何做出最佳的选择,而且这种选择
全部是在编译期完成的。
模板的机制:特化 和 实参演绎
1、特化
基本模板:
template
class A { // (1)
void f(T1 a, T2 b)
}
局部特化(偏特化):
template class A { // (2)
void f(int a, T2 b)
}
或者
template>class A { // (3)
void f(T a, T b)
}
全局特化(显式特化):
template<>
class A {
void f(int a, int b)// (4)
}
使用示例:
A* p1//将使用(4) ——全局特化
A* p2//将使用(3) ——局部特化
A* p3//将使用(2) ——局部特化
A* p4//将由(1) ——基本模板——生成
//A
优点:
由:全局特化->局部特化->基本模板,这种特化顺序的选择与匹配(重载解析规则)是由编译器自动进行的,无需人工参与。
可以根据不同的情况(诸如类型不同,条件不同),给出不同的实现,从而获得更加灵活的针对性。
可以针对任何变化,改善了程序的扩展性。
2 实参演绎
T const&f(T const&a, T const&b)
{
return a + b//1处
}
int g = f(1,2)
实际上f(1,2)要匹配的函数是int const&f(int const&,int const&)
而这个函数又是怎么来的呢?
优点:
再也无需提供一对尖括号和里面的实参,诸如f(1,2),有了
实参演绎,我们就可以写成f(1,2)。
模板的应用
1、标准库(STL)——到处都是模板代码
标准库=算法+容器+迭代器
如list /
2、类型无关性(T)
3、trait和policy
(1)trait: 主要用到了许多typedef和特化,指定的是一种特性。
// traits/accumtraits3.hpp
template
lass AccumulationTraits
c template<>
class AccumulationTraits {
public:
typedef int AccT
static AccT const zero = 0
}
template<>
class AccumulationTraits {
public:
typedef int AccT
static AccT const zero = 0
}
template<>
class AccumulationTraits {
public:
typedef long AccT
static AccT const zero = 0
}
(2)policy:通常表现为某个函数,指定的是一种行为
class SumPolicy {
public:
template
static void accumulate (T1&total, T2 const &value) {
total += value
}
}
(3)trait和policy的用法:
template>
class Accum {
public:
typedef typename Traits::AccT AccT
static AccT accum (T const* beg, T const* end) {
AccT total = Traits::zero()
while (beg != end) {
Policy::accumulate(total, *beg)
++beg
}
return total
}
}
4、Metaprogramming
编译期计算、递归的思想
5、新形式的设计模板
(第三、第四、第五点以后再详细介绍)
《C++ Templates中文版》的具体介绍
第1部分介绍了模板的基本概念,以教程的风格来介绍这些基本概念。
第2部分阐述了模板的语言细节,可以作为一本基于模板的构造的参考手册。
第3部分介绍了C++模板所支持的基本设计技术,范围覆盖从微小的概念一直延伸到复杂的用法;一些技术在别的书籍都没有出现过。
第4部分基于前两部分,深入讨论了各种使用模板的普通应用程序。
C语言经典小程序
用vs,vc都可以正常运行
#include
#include
#include
// 获取控制台窗口句柄
HWND GetConsoleHwnd(void)
{
#define MY_BUFSIZE 1024 // Buffer size for console window titles.
HWND hwndFound// This is what is returned to the caller.
char pszNewWindowTitle[MY_BUFSIZE]// Contains fabricated
char pszOldWindowTitle[MY_BUFSIZE]// Contains original
GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE)//获取控制台标题存入pszOldWindowTitle中
//设置控制台的标题为 时间数 进程ID
wsprintf(pszNewWindowTitle,"%d/%d",//把获取的数目,和当前进程ID输出到缓冲区pszNewwindowtitle中
GetTickCount(),//用于获取 *** 作数茄系统启动后的毫秒薯桐察数
GetCurrentProcessId())/轮友/获取当前进程ID
SetConsoleTitle(pszNewWindowTitle)//更改控制台的标题为新内容
Sleep(40)
hwndFound=FindWindow(NULL, pszNewWindowTitle)//获取控制台的HWND号
SetConsoleTitle(pszOldWindowTitle)//更改控制台的标题为原始内容
return(hwndFound)//返回句柄
}
{
HWND hWnd=GetConsoleHwnd()//获取控制台窗口句柄,用于设置画笔颜色
HDC hDC=GetDC(hWnd)
COORD dwSize//记录窗体大小,用于设定坐标轴远点
HPEN hNewPen=CreatePen(PS_SOLID,1,RGB(255,0,0))//创建画笔对象
HPEN hOldPen=(HPEN)SelectObject(hDC,hNewPen)//选取画笔对象进行绘图
CONSOLE_SCREEN_BUFFER_INFO bInfo// 窗口信息
HANDLE Hout=GetStdHandle(STD_OUTPUT_HANDLE)//获取控制台句柄
GetConsoleScreenBufferInfo(Hout, &bInfo )//获取控制台信息
dwSize=bInfo.dwMaximumWindowSize //获取窗口大小,此时获得的是字符模式下
//从字符到图像放大坐标轴8倍
dwSize.X *=8
dwSize.Y*=8
SetBkMode(hDC, TRANSPARENT)SetTextColor(hDC,255*255)
//绘制X轴各个特殊坐标
TextOut(hDC,dwSize.X-15,dwSize.Y/2-15,"X",1)
//Arc(hDC,100,100,300,300,350,500,350,500)//画圆 其中hDC表示画图句柄,100,100,300,300表示所使用的矩形区域,350,500表示画弧线的起点,350,500表明画弧线的终点
//绘制Y轴各个特殊坐标
TextOut(hDC,dwSize.X/2,0,"Y",1)
MoveToEx(hDC,0,dwSize.Y /2,NULL)
LineTo(hDC,dwSize.X,dwSize.Y/2)
MoveToEx(hDC,dwSize.X/2,0,NULL)
LineTo(hDC,dwSize.X/2,dwSize.Y)
ReleaseDC(hWnd,hDC)
}
void draw(double p)
{
int i
double x,y
HWND hWnd=GetConsoleHwnd()//获取控制台窗口句柄,用于设置画笔颜色
HDC hDC=GetDC(hWnd)
COORD dwSize//记录窗体大小,用于设定坐标轴远点
HPEN hNewPen=CreatePen(PS_SOLID,1,RGB(255,0,0))//创建画笔对象
HPEN hOldPen=(HPEN)SelectObject(hDC,hNewPen)//选取画笔对象进行绘图
CONSOLE_SCREEN_BUFFER_INFO bInfo// 窗口信息
HANDLE Hout=GetStdHandle(STD_OUTPUT_HANDLE)//获取控制台句柄
GetConsoleScreenBufferInfo(Hout, &bInfo )//获取控制台信息
dwSize=bInfo.dwMaximumWindowSize //获取窗口大小,此时获得的是字符模式下
//从字符到图像放大坐标轴8倍
dwSize.X *=8
dwSize.Y*=8
//MoveToEx(hDC,0,dwSize.Y/2,NULL)
for(i=-180i
{
x=16*pow(sin(i*3.1415926/180),3.0)*p
y=(13*cos(i*3.1415926/180)-5*cos(2*i*3.1415926/180)-2*cos(3*i*3.1415926/180)-cos(4*i*3.1415926/180))*p
x=(x+16)*dwSize.X/32/2+dwSize.X/4
y=-y/16*dwSize.Y/2.3+dwSize.Y/2
x=x
y=y
MoveToEx(hDC,x,y,NULL)
LineTo(hDC,x+1,y+1)
}
}
void main()
{
double p
for(p=0.6p
draw(p)
system("PAUSE")
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)