vc2013 x64属性区怎么做出来的

求助,18MC模式不能用VC买属性
如图,在属性升级这里完全点不动,这可咋整啊,难道要60终老了么...求大神帮助啊
8分钟惨案...?真心求帮助啊啊啊啊啊
PC端Steam上玩的
重新开个档吧
引用3楼 @ 发表的:重新开个档吧求问老铁,这是游戏Bug么...
引用4楼 @ 发表的:求问老铁,这是游戏Bug么...差不多,之前好像看到过有人遇到这个BUG,大家都是建议重新开档的
我就是这样,重新开吧
引用5楼 @ 发表的:差不多,之前好像看到过有人遇到这个BUG,大家都是建议重新开档的这特么一晚上白玩了...队内试训好不容易刷到A+评分?
引用7楼 @ 发表的:这特么一晚上白玩了...队内试训好不容易刷到A+评分?额,慢慢肝吧
重新来个呗
您需要登录后才可以回复,请或者
684人参加团购489.00元&749.00元
1327人参加团购509.00元&999.00元
189人参加团购549.00元&1099.00元
471人参加团购279.00元&449.00元
696人参加团购398.00元&999.00元
1376人参加团购348.00元&1199.00元
1123人参加团购398.00元&1499.00元
227人参加团购395.00元&899.00元
315人参加团购479.00元&999.00元
870人参加团购448.00元&1299.00元
595人参加团购174.80元&399.00元
916人参加团购298.00元&899.00元匿名用户不能发表回复!|当前位置: >>
Visual C++ 程序设计张 淼 哈尔滨工业大学(威海)计算机学院 ? 课程安排? 授课24学时 ? 实验16学时? 考试:? 平时成绩(作业+出勤) 15% ? 实验成绩 15% ? 考试 70%计算机科学与技术学院张淼2 Visual C++到底是什么?计算机科学与技术学院张淼3 C语言自产生以来,出现了许多C语言的 集成开发环境,如Turbo C、Borland C等, 在这些集成开发环境中,程序员可以将代 码的编辑、编译、连接、执行和调试过程 全部完成。回顾计算机科学与技术学院张淼4 面向对象的程序设计语言C++产生之后, 又出现了Borland C++、C++ Builder 和Visual C++等针对C++语言的集成开 发环境。虽然这些C++集成开发环境是针 对C++语言的,而且增加了许多其它特性, 然而单就C程序来讲,如果符合ANSI C的 标准,在这些集成环境中都能够很好地编译 和连接。5计算机科学与技术学院张淼 VC++主要是用来开发Windows应 用程序的。Windows程序设计不同 于DOS下的程序设计,它是一种事件驱 动的程序设计模式,主要是基于消息 的。计算机科学与技术学院张淼6 Visual C++? Windows环境下最主要的应用开发系统之 一。 ? C++语言的可视化集成开发环境。 ? 强大的调试功能为大型复杂软件的开发提供 了有效的排错手段。计算机科学与技术学院张淼7 使用VC++进行Windows应用程序 设计时,有两种方法:一是使用 Platform SDK,另一种方法是直 接使用Microsoft提供的MFC类库。计算机科学与技术学院张淼8 Platform SDK(software develop kit ): 使用C语言和Win32 API (Application Programming Interface,应用程序编 程接口)函数进行编程。 MFC: 使用C++语言和MFC(微软基础类库)进行 编程.计算机科学与技术学院 张淼 9 Visual C++ Programming MFC Programming计算机科学与技术学院张淼10 SDK简单、易于理解 工作量大、效率低MFC复杂,代码可读性差 工作量小,效率高计算机科学与技术学院张淼11 SDK编程方式易于理解 Windows 工作原理。通过了解相对已 “过时”的 Win32 SDK编 程,有助于理解以 后的很多东西!计算机科学与技术学院 张淼 12 C++/MFC程序设计必须跨越的四大技术障碍? 面向对象观念与C++语言 ? Windows程序基本观念 ? Microsoft Foundation Classes(MFC) 本身 ? Visual C++集成开发环境与各种开发工具 (难度不高,但需熟练)计算机科学与技术学院张淼13 课程安排? 学时安排? 24学时? 课程内容? Windows编程基础? 3学时? 面向对象程序设计和C++语言基础(书1-3章)? 13学时? MFC(Microsoft Foundation Classes) (书4-9章)? 8学时计算机科学与技术学院张淼14 推荐书籍? C++ 编程思想(第2版) ? Bruce Eckel,机械工业出版社 ? C++ Primer (第3版)中文版 ? Stanley B.Lippman,Josee Lajoie,中国电力出版社 ? Windows 程序设计(第5版) ? Charles Petzold,北京大学出版社 ? MFC Windows 程序设计(第2版) ? Jeff Prosise ,清华大学出版社 ? 深入浅出MFC(第二版) ? 侯俊杰,华中科技大学出版社 ? Visual C++ 技术内幕 ? George Shepherd,David Kruglinski ,清华大学出版社 ? 深入解析MFC (MFC Internals )? George Shepherd ,中国电力出版社计算机科学与技术学院 张淼 15 第一部分 Windows编程基础计算机科学与技术学院张淼16 ? Windows程序内部运行原理 ? SDK方式编写windows应用程序 ? Windows应用程序特性计算机科学与技术学院张淼17 CH1.1Windows程序内部运行原理? 目标:理解Windows程序的运行机制 ? 掌握以下基本概念:? ? ? ? ? 窗口 API 消息与消息机制 消息响应 句柄计算机科学与技术学院张淼18 Windows应用程序,操作系统,计算机硬件输入输出设备 之间的相互关系应用程序③ ④消息队列操作系统① ②输入输出设备计算机科学与技术学院 张淼 19 API操作系统所能够完成的每一个特殊功能 通常都有一个函数与其对应,也就是说,操 作系统把它所能够完成的功能以函数的形式 提供给应用程序使用,应用程序对这些函数 的调用就叫做系统调用(System call), 这些函数的集合就是Windows操作系统提 供给应用程序编程的接口(Application Programming Interface),简称 Windows API。计算机科学与技术学院 张淼 20 API? 什么是API?? Application Programming Interface? API的作用? 是Windows系统与Windows应用程序间的 标准程序接口 ? Windows应用程序可以利用标准大量API函 数调用系统功能? 窗口管理函数:实现窗口的创建、移动和修改功能 ? 系统服务函数:实现与操作系统有关的多种功能 ? 图形设备(GDI)函数:实现与设备无关的图形操 作功能计算机科学与技术学院 张淼 21 Windows应用程序,操作系统,计算机硬件输入输出设备 之间的相互关系应用程序③ ④消息队列操作系统① ②输入输出设备计算机科学与技术学院 张淼 22 消息响应操作系统能够感知输入设备的变化(事 件),并且能够知道具体的事件情况, 但操作系统并不决定对这一事件如何作 出反应,而是将这一事件转交给应用程 序,由应用程序决定如何对这一事件作 出反应。对事件作出反应的过程就是消 息响应。计算机科学与技术学院张淼23 消息操作系统是怎样将感知到的事件传 递给应用程序的呢?这是通过消息 机制(Message)来实现的。操作 系统将每个事件都包装成一个称为 消息的结构体MSG来传递给应用 程序。计算机科学与技术学院张淼24 消息MSG结构定义如下: typedef struct tagMSG { HWND UINT WPARAM wP LPARAM lP DWORD POINT } MSG;计算机科学与技术学院 张淼 25 消息? 消息结构体 - MSG? 主消息:由事先定义好的消息名标识 ? 附加消息:与主消息有关? wParam ? lParamtypedef struct tagMSG{ HWND //窗口句柄 UINT //主消息 WPARAM wP //附加消息 LPARAM lP DWORD //送至队列的时间 POINT //消息发送时屏幕光标的位置 } MSG, *PMSG;计算机科学与技术学院 张淼 26 ? Windows窗口是Windows系统的一个 内部数据结构的实例,由一个“窗口句柄” 标识,Windows系统创建它并给它分配系 统资源。 ? Windows Object是Windows系统的 内部结构,通过一个句柄来引用;计算机科学与技术学院张淼27 句柄(Handle)? 句柄(HANDLE),资源的标识。 ? 操作系统要管理和操作这些资源,都是通过 句柄来找到对应的资源。按资源的类型,又 可将句柄细分成图标句柄(HICON),光 标句柄(HCURSOR),窗口句柄 (HWND),应用程序实例句柄 (HINSTANCE)等等各种类型的句柄。操 作系统给每一个窗口指定的一个唯一的标识 号即窗口句柄。计算机科学与技术学院张淼28 从变量的类型区分变量的用途int x,y; x=50; y=30; //x和y既可以用来表示坐标点,也可以用来表示 宽度和高度,还可以用来表示身高和体重等等。 typedef int WIDTH typedef int HEIGHT WIDTH HEIGHT //好处:我们从变量的类型上就可以知道x和y 是用来表示宽度和高度。计算机科学与技术学院 张淼 29 typedef struct tagPOINT { LONG LONG } POINT;计算机科学与技术学院张淼30 ? 对于MSG这个结构体来说,它里面包含的 信息是相当丰富的,它包含了对于一个消息 来说,它和哪一个窗口相关,这个消息本身 是什么,这个消息的附加参数是什么,消息 发生投递的时间是什么。我们拿到这样一个 消息就像当全面了。那么我们就知道应该做 什么样的处理。计算机科学与技术学院张淼31 Windows应用程序,操作系统,计算机硬件输入输出设备 之间的相互关系应用程序③ ④消息队列操作系统① ②输入输出设备计算机科学与技术学院 张淼 32 消息队列对于每一个应用程序,操作系统会给它建立一个 消息队列。这个队列实际上是一个先进先出的缓 冲区,通常是一个某种变量类型的数组。消息队 列中的每个元素都是一条消息。 操作系统将生成的每个消息按先后顺序放进消息 队列中。应用程序总是依次取走队列里的第一条 消息。应用程序取走消息后便能够知道用户的操 作和程序状态的变化,从而对特定的消息进行处 理(编写代码)――消息响应。计算机科学与技术学院 张淼 33 计算机科学与技术学院张淼34 CH1.2 SDK方式编写windows应用程序? 目标:能够用SDK(Windows API+C)编写 一个简单的windows应用程序,通过编写 程序掌握Windows程序的运行原理及编写 方式。为MFC的学习打下基础。计算机科学与技术学院张淼35 程序执行的起点(入口函数)?main()WinMain()计算机科学与技术学院张淼36 WinMain函数Windows程序的入口函数int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow // show state );计算机科学与技术学院张淼37 匈牙利表示法? 一种命名约定 匈牙利命名法是微软推广的一种关于变量、 函数、对象、前缀、宏定义等各种类型的符 号的命名规范。匈牙利命名法的主要思想是: 在变量和函数名中加入前缀以增进人们对程 序的理解。? 为纪念Microsoft程序员Charles Simonyi 所使用的命名约定计算机科学与技术学院张淼38 窗口的创建创建一个完整的窗口需要经过下面四个操作步骤: ? 设计一个窗口类; ? 注册窗口类; ? 创建窗口; ? 显示及更新窗口。计算机科学与技术学院张淼39 创建窗口 - 第一步? 窗口类的定义- WNDCLASStypedef struct tagWNDCLASS{ UINT //窗口类风格 WNDPROC lpfnWndP //窗口过程函数 int cbClsE //在类结构中预留的空间 int cbWndE //在Windows内部预留空间 HINSTANCE hI //程序实例句柄 HICON hI //窗口的图标 HCURSOR hC //光标句柄 HBRUSH hbrB //背景色 LPCTSTR lpszMenuN //窗口类菜单 LPCTSTR lpszClassN //窗口类名 } WNDCLASS, *PWNDCLASS;计算机科学与技术学院张淼40 窗口类的类型在我们的程序中经常要用到一类变量,这个变量 里的每一位(bit)都对应某一种特性。当该变量的 某位为1时,表示有该位对应的那种特性,当该位 为0时,即没有该位所对应的特性。当变量中的某 几位同时为1时,就表示同时具有几种特性的组合。 一个变量中的哪一位代表哪种意义,不容易记忆, 所以我们经常根据特征的英文拼写的大写去定义 一些宏,该宏所对应的数值中仅有与该特征相对 应的那一位(bit)为1,其余的bit都为0。计算机科学与技术学院张淼41 如果我们希望某一变量的数值既有 CS_VREDRAW特性,又有CS_HREDRAW特性, 我们只需使用二进制OR(|)操作符将他们进行或 运算相组合,如style=CS_VREDRAW | CS_HREDRAW | CS_NOCLOSE。如果我们希 望在某一变量原有的几个特征上去掉其中一个特 征,用取反(~)之后再进行与(&)运算,就能 够实现,如在刚才的style的基础上去掉 CS_NOCLOSE特征,可以用style & ~CS_NOCLOSE实现。计算机科学与技术学院 张淼 42 窗口过程函数? 窗口过程函数用来对消息进行处理 第二个成员变量lpfnWndProc指定了这一类型 窗口的过程函数,也称回调函数。计算机科学与技术学院张淼43 回调函数当应用程序收到给某一窗口的消息时(还记 得前面讲过的消息通常与窗口相关的吗?), 就应该调用某一函数来处理这条消息。这一 调用过程不用应用程序自己来实施,而由操 作系统来完成,但是,回调函数本身的代码 必须由应用程序自己完成。计算机科学与技术学院张淼44 对于一条消息,操作系统到底调用应用 程序中的哪个函数(回调函数)来处理 呢?操作系统调用的就是接受消息的窗口所属的类型中的lpfnWndProc成员指 定的函数。每一种不同类型的窗口都有自己专用的回调函数,该函数就是通过 lpfnWndProc成员指定的。计算机科学与技术学院张淼45 LoadIconLoadIcon的作用是在应用程序中加载一个窗口图标, 其原型为: HICON LoadIcon( HINSTANCE hInstance, LPCTSTR lpIconName );图标资源名或系统 预定义图标标识名 图标资源所在的模块句柄, NULL则使用系统预定义图标计算机科学与技术学院张淼46 LoadCursorLoadCursor的作用是在应用程序中加载一个窗口光标,其原型为: HCURSOR LoadCursor( HINSTANCE hInstance, LPCTSTR );光标资源所在的模 块句柄,NULL则使 用系统预定义光标光标资源名或系统 预定义光标标识名lpCursorName计算机科学与技术学院张淼47 GetStockObjectGetStockObject的作用是获取笔、画刷、 调色板、字体的句柄。应用程序调用函数 GetStockObject获取系统提供的背景刷。 其原型为:HGDIOBJ GetStockObject( int fnObject // type of stock object );计算机科学与技术学院张淼48 创建窗口 - 第二步? 注册窗口类 - RegisterClassATOM RegisterClass( CONST WNDCLASS *lpWndClass );计算机科学与技术学院张淼49 创建窗口 - 第三步? 创建窗口实例- CreateWindowHWND CreateWindow ( LPCTSTR lpszClassName,//窗口类名 LPCTSTR lpszTitle, //窗口标题名 DWORD dwStyle, //创建窗口的样式 int x,y, //窗口左上角坐标 int nWidth,nHeight, //窗口宽度和度高 HWND hwndParent, //该窗口的父窗口句柄 HWENU hMenu, //窗口主菜单句柄 HINSTANCE hInstance, //创建窗口的应用程序当前句柄 LPVOID lpParam //指向一个传递给窗口的参数值的指针 )计算机科学与技术学院张淼50 窗口样式常用窗口样式标识 WS_BORDER WS_CAPTION WS_VSCROLL WS_MAXIMIZEBOX WS_MAXIMIZE WS_MINIMIZEBOX WS_MINIMIZE WS_OVERLAPPED WS_OVERLAPPEDWINDOW WS_POPUP WS_POPUPWINDOW WS_SYSMENU WS_HSCROLL 说明 创建一带边框的窗口 创建一带标题栏的窗口 创建一带垂直滚动条的窗口 创建一带最大化框的窗口 创建一最大尺寸的窗口 创建一带最小化框的窗口 创建一最小尺寸的窗口 创建一带边框和标题的窗口 创建一带边框、标题栏、系统菜单及最大、 最小化框的窗口 创建一弹出式窗口 创建一带边框和系统菜单的弹出式窗口 创建一带系统菜单的窗口 创建一带水平滚动条的菜单计算机科学与技术学院张淼51 创建窗口 - 第四步? 显示窗口 - ShowWindowBOOL ShowWindow( HWND hWnd,int nCmdShow );SW_HIDE SW_SHOWNORMAL SW_SHOWMINIMIZE SW_SHOWMAXMIZE SW_SHOWNOACTIVE SW_RESTORE计算机科学与技术学院 张淼隐藏窗口 显示并激活窗口 显示并最小化窗口 显示并最大化窗口 显示但不激活窗口 恢复窗口的原来位置及尺寸52 创建窗口 - 第五步? 刷新窗口 - UpdateWindowBOOL UpdateWindow( HWND hWnd );显示窗口后,应用程序调用UpdateWindow更新并绘制用户区, 并发出WM_PAINT消息。 UpdateWindow(hwnd);计算机科学与技术学院张淼53 GetMessage从消息队列中读取 一条消息,并将消 息放在MSG结构中返回零值,即检索 到WM_QUIT消息,程 序结束循环并退出其中函数GetMessage形式为: GetMessage( lpMSG, //指向MSG结构的指针 hwnd, nMsgFilteMin, //用于消息过滤的最小消息号值 nMsgFilterMax //用于消息过滤的最大消息号值 )计算机科学与技术学院 张淼 54 ? 从消息队列中获取消息? GetMessage? 翻译消息和派遣消息? TranslateMessage ? DispatchMessage将消息传递给 窗口过程进行 处理Windows 产生的消息消 息 队 列计算机科学与技术学院张淼55 计算机科学与技术学院张淼56 Windows系统 排队消息WM_KEYDOWN WM_KEYUP WM_MOUSEMOVE WM_LBUTTONDOWN WM_QUIT … ...非排队消息WM_CREATE WM_DESTROY WM_SIZE WM_PAINT … ...① DefWindowProc 应用程序的 消息队列 ()检索到 的消息 ③ GetMessage ② () ⑤WinMain()消息 循环 DispatchMessage ④ ()应用程序回调WndProc()case 1 case 2 case 3 … Default⑥计算机科学与技术学院张淼57 窗口过程? 窗口过程函数用来对消息进行处理LRESULT CALLBACK WndProc ( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );计算机科学与技术学院张淼58 窗口函数的一般形式如下:LRESULT CALLBACK WndProc( HWND hwnd, UINT messgae, WPARAM wParam,LPARAM lParam ) { … switch(message) ∥ message为标识的消息 { case … 在消息处理程序段中一般都有对WM_DESTROY … 的处理,该消息是关闭窗口时发出的。它向应用 程序发出WM_QUIT消息,请求退出处理函数: void PostQuitMessage(int nExitCode) …case WM_DESTROY: PostQuitMessage(0); default:return DefWindowProc(hwnd,message,wParam,lParam);//nExitCode为应用程序的退出代码} 为未定义处理过程的消息提供缺省处理 return(0); } 计算机科学与技术学院 张淼59 程序执行流程程序从WinMain开始进行程序初始化 创建窗口注册窗口函数 用GetMessage取消息 默认处理 否 退出消息 是 退出程序计算机科学与技术学院 张淼 60处理消息 是否拦截消息 格式化字符串函数? 一个常用的格式化字符串的函数? printf ? stdio.hchar szChar[20]; sprintf(szChar,&char is %d&,wParam);计算机科学与技术学院张淼61 MessageBox函数? 用于显示信息int //返回用户所选按钮代表的数值 MessageBox ( HWND hWnd, //窗口句柄 LPCTSTR lpText, //消息框主体显示的文本 LPCTSTR lpCaption, //消息框标题栏显示文本 UINT uType //代表消息框风格的常数组合 );计算机科学与技术学院张淼62 消息框风格? 以MB_开始的常数组合代表消息框的风格? 多种风格之间用“|”分隔#include &windows.h& int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) { if(IDOK == MessageBox( NULL, &是否退出本程序?&, &退出&, MB_OKCANCEL|MB_ICONQUESTION)) MessageBox(NULL,&再见!&,&退出&,MB_OK); return 0; }计算机科学与技术学院 张淼 63 设备描述表( Device context )? 设备描述表(设备上下文):系统内部维护 的一个数据结构,该结构包含应用程序向输 出设备输出时所需要的信息。是应用程序和 输出设备之间的桥梁。不允许应用 程序 Windows系统 外设提供 统一的设备环境DC使应用程序和设备相连计算机科学与技术学院 张淼 64 应用程序每一次文字图形操作均参照设备描述表 中的属性进行。设备描述表描述了特定输出设备 状态、文本和图形的绘图参数等;包括设备上可 使用的输出区域、逻辑坐标系、选定何种绘图工 具绘图、绘图前景色、填充色、字体、字体颜色、 字的磅数等属性。计算机科学与技术学院张淼65 GDI简介? GDI - 图形设备接口? 要在窗口的客户区绘图,可以使用Windows 的图形设备接口(GDI)函数 ? GDI的重要部分:设备描述表(DC)? GDI内部保存的数据结构 ? 设备无关性? 每个GDI函数都需要将设备描述表句柄作为函 数的第一个参数,例如? DrawText( HDC, LPCTSTR, int, LPRECT, UINT ); ? TextOut( HDC, int, int, LPCTSTR, int );计算机科学与技术学院 张淼 66 获取设备描述表:方法一? 该方法适合于处理非WM_PAINT消息? 用GetDC获取设备描述表句柄 ? 用ReleaseDC释放设备描述表句柄? 这种获取设备描述表的一般方式如下hdc = GetDC(hwnd) ; …… ReleaseDC(hwnd, hdc) ;计算机科学与技术学院张淼67 WM_PAINT消息? 什么时候向窗口过程发送WM_PAINT消 息(窗口发生重绘) - “无效”的时候? ? ? ? 调用UpdateWindow函数刷新窗口 窗口的全部或者部分失效的时候 窗口从无到有 手动刷新窗口? 调用InvalidateRect函数计算机科学与技术学院张淼68 ? Windows系统为每一个窗口建立了一个 PAINTSTRUCT结构。该结构中包含了包 围无效区域的一个最小矩形的结构RECT, 应用程序可以根据这个无效区域执行更新的 操作。 PAINTSTRUCT结构体不需要我 们维护,是系统内部维护的结构体。计算机科学与技术学院张淼69 获取设备描述表:方法二? 该方法只适合于处理WM_PAINT消息? 用BeginPaint“使无效窗口生效”并“返回设 备描述表句柄” ? 用EndPaint释放设备描述表句柄? 一般处理WM_PAINT的形式如下:Case WM_PAINT; hdc = BeginPaint(hwnd, &ps) ; …… EndPaint(hwnd, &ps) ; return 0 ;计算机科学与技术学院张淼70 与输出文本相关的几个函数? 设置文本颜色? SetTextColor(HDC,COLORREF);? 设置文本背景色? SetBkColor(HDC,COLORREF);? 设置文本显示模式? SetBkMode(HDC,int iBkMode);? iBkMode? OPAQUE ? TRANSPARENT //不透明 //透明计算机科学与技术学院张淼71 画线? 画线? LineTo? LineTo(HDC,int,int);? 例:LineTo(hdc,100,100); ? 默认情况下从(0,0)开始画? 移动画笔? MoveToEx? MoveToEx(HDC,int,int,LPPOINT);计算机科学与技术学院张淼72 画其它图形? 画椭圆? Ellipse(hdc,100,100,200,200);? 画圆角矩形? RoundRect(hdc,……);? 画弧? Arc(hdc,……);? 画饼? Pie(hdc,……);? 画矩形? Rectangle(HDC,int,int,int,int);计算机科学与技术学院 张淼 73 画笔 - HPEN? 创建画笔HPEN hP hPen = CreatePen(PS_SOLID,2,RGB(255,0,0)); // 线形,线宽,颜色? 将画笔选入DCSelectObject(hdc,hPen);? 删除画笔资源DeleteObject(hPen);计算机科学与技术学院张淼74 画刷 - HBRUSH? 创建画刷HBRUSH hB hBrush = CreateSolidBrush(RGB(255,0,0));? 将画刷选入DCSelectObject(hdc,hBrush);? 删除画刷资源DeleteObject(hBrush);计算机科学与技术学院张淼75 画刷? 取得系统自带画刷HBRUSH hB hBrush = (HBRUSH)GetStockObject(BLACK_BRUSH); //WHITE_BRUSH //GRAY_BRUSH //DKGRAY_BRUSH //……计算机科学与技术学院张淼76 获取设备描述表:方法三? 获取整个窗口的设备描述表? 用GetWindowDC获取整个窗口的设备描述表 句柄 ? 用ReleaseDC释放设备描述表句柄HDC Hdc = GetWindowDC(hWnd); //使用设备描述表 …… ReleaseDC(hWnd,hdc);参见工程0302计算机科学与技术学院 张淼 77 获取设备描述表:方法四? 获取整个屏幕的设备描述表? 用CreateDC获取整个屏幕的设备描述表句柄 ? 用DeleteDC释放设备描述表句柄HDC Hdc = CreateDC(&DISPLAY&,NULL,NULL,NULL); //使用设备描述表 …… DeleteDC(hdc);参见工程0302计算机科学与技术学院 张淼 78 常用消息? WM_CREATE? 由CreateWindow函数发出的消息? WM_PAINT? 窗口客户区的全部或者部分“无效”时触发? WM_CLOSE? 关闭窗口时产生的消息? WM_DESTROY? 由DestroyWiodow函数发出的消息? WM_QUIT? 由PostQuitMessage函数发出的消息计算机科学与技术学院 张淼 79 进队消息与不进队消息? 进队消息? 进队消息是由Windows放入程序的消息队列 中的? 不进队消息? 不进队消息直接发送给窗口过程? 窗口过程? 窗口过程是窗口的“消息中心”计算机科学与技术学院张淼80 函数调用约定? 函数调用是通过栈来实现的。在调用时,将 参数值和调用后的返回地址压入所分配的栈 空间中。函数计算结束以后,或者调用者、 或者函数本身修改堆栈,使堆栈恢复原装。 在参数传递中,有两个很重要的问题必须得 到明确说明:? 当参数个数多于一个时,按照什么顺序把参数 压入堆栈 ? 函数调用后,由谁来把堆栈恢复原装(堆栈清 除)计算机科学与技术学院张淼81 函数调用约定? 在高级语言中,通过函数调用约定来说明这 两个问题。常见的调用约定有:? ? ? ? ? stdcall cdecl fastcall thiscall naked call计算机科学与技术学院张淼82 头文件? windows.h(所有windows程序都必须 载入windows.h)? 是主要的包含文件,是给Windows程序开发 人员的总的接口头文件 ? 其中包含如下头文件? ? ? ? ? ? windef.h winnt.h winbase.h winuser.h wingdi.h ……张淼基本类型定义 支持Unicode的类型定义 内核函数 用户接口函数 图形设备接口函数计算机科学与技术学院83 Windows程序分为“程序代码”和 “用户接口(UI)资源”两大部分。 程序代码使用编译器编译,用户接口资 源使用资源编译器编译,最后两者使用 连接器加上库文件可以生成可执行文件。计算机科学与技术学院张淼84 动态链接库? 自从微软推出第一个版本的Windows操作 系统以来,动态链接库(DLL)一直是 Windows操作系统的基础。计算机科学与技术学院张淼85 ? 动态链接库通常都不能直接运行,也不能接收 消息。它们是一些独立的文件,其中包含能被 可执行程序或其它DLL调用来完成某项工作的 函数。只有在其它模块调用动态链接库中的函 数时,它才发挥作用。 ? Windows API中的所有函数都包含在DLL中。 其中有3个最重要的DLL,Kernel32.dll,它包 含用于管理内存、进程和线程的各个函数; User32.dll,它包含用于执行用户界面任务 (如窗口的创建和消息的传送)的各个函数; GDI32.dll,它包含用于画图和显示文本的各 个函数。计算机科学与技术学院 张淼 86 静态库和动态库? 静态库:函数和数据被编译进一个二进制文件(通 常扩展名为.LIB)。在使用静态库的情况下,在编 译链接可执行文件时,链接器从库中复制这些函数 和数据并把它们和应用程序的其它模块组合起来创 建最终的可执行文件(.EXE文件)。 ? 在使用动态库的时候,往往提供两个文件:一个引 入库和一个DLL。引入库包含被DLL导出的函数 和变量的符号名,DLL包含实际的函数和数据。在 编译链接可执行文件时,只需要链接引入库,DLL 中的函数代码和数据并不复制到可执行文件中,在 运行的时候,再去加载DLL,访问DLL中导出的 函数。计算机科学与技术学院 张淼 87 用户接口(UI)资源是指功能菜单、对话框、程 序图标、光标等资源,它是Windows应用程序界面 的重要组成部分。资源的使用极大方便了应用程序界 面的设计,也大大方便了应用程序与用户的交互。 这些用户资源的实际内容(二进制代码)是借助 各种工具产生的。并以各种扩展名的文件存在, 如.ico,.bmp,.cur等。程序员必须在一个所谓的资 源描述文档(.rc)中描述它们。RC编译器读取RC文 件的描述后,将所有用户接口资源文件集中制作一 个.RES文件。 这些资源可以使用VC++6.0提供的资源编辑器 来实现创建和编辑。计算机科学与技术学院 张淼 88 资源? 资源分类? 菜单? WM_COMMAND消息? wParam低16位传递菜单项资源ID? 对话框? WM_COMMAND消息? wParam低16位传递子窗口(控件)资源ID? ……? 资源ID? 资源的唯一标识计算机科学与技术学院张淼89 ? Windows应用程序加载菜单的方法: 在窗口类的定义中加载菜单资源 wndcls.lpszMenuName=MAKEINTRESOU RCE(IDR_MENU1); ? 在创建窗口时加载菜单 HMENU hM hMenu=LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)) ? 动态加载菜单:应用程序通过调用函数 LoadMenu获取菜单句柄后,还可通过 SetMenu动态加载菜单。计算机科学与技术学院 张淼 90 CH1.3 windows应用程序特性? ? ? ? 消息驱动机制 图形设备接口(GDI) 基于资源的程序设计 动态链接库计算机科学与技术学院张淼91 总结:? ? ? ? ? ? ? API 消息机制(MSG) 句柄 GDI 设备上下文(DC) 动态链接库 资源与资源ID计算机科学与技术学院张淼92 作业:1、理解Windows程序设计的基本概念 2、书后习题P118 (7)计算机科学与技术学院张淼93 第二部分面向对象程序设计和 C++语言基础计算机科学与技术学院 张淼 94 C++语言的产生? C++是从C语言发展演变而来的,首先是一 个更好的C。 ? 引入了类的机制,最初的C++被称为&带类 的C&。 ? 1983年正式取名为C++。C++语言的标 准化工作从1989年开始,于1994年制定 了ANSI C++标准草案。以后又经过不断 完善,成为目前的C++。计算机科学与技术学院张淼95 C++语言与C语言的关系C++语言※保持与C语言的相兼性 ※是C语言的一个超集※使得C++不是一个纯面向 对象的程序设计语言 ※C++语言对C语言作了很 多改进C语言支持面向过程 的程序设计语 言◆ C++语言与C语言的本质区别――C++语言支持面向对象的程序设计 C语言仅支持面向过程的程序设计 学好C++语言的关键计算机科学与技术学院 张淼掌握好面向对象的程序设计思想96 ? 打着面向对象的幌子干着面向过程的勾当!? C++ 编译器对 C 程序的兼容性造成了最底层 的“过程勾当”。 ? 实际上用 C++ 编程的人,大部分不自己创建 类,而是使用类库,这样就造成了他们把类库 作为一种高级的库函数库来理解,并没有真正 理解面向对象的思想。 ? C++ 给了我们第二条道路去走过程编程计算机科学与技术学院张淼97 C++语言基础? C/C++语言概述(结构化程序设计部分) ? C++面向对象程序设计基础 ? C++面向对象程序设计进阶计算机科学与技术学院张淼98 控制台(console)应用程序? DOS-like程序。 ? 仍然可以调用部分的、不牵扯到图形使用者接口 (GUI)的Win32 API(尤其是KERNEL.DLL 模块所提供的那一部分),所以它可以使用 Windows提供的各种高级功能,它可以产生进程, 产生线程。甚至还可以在其中使用部分的MFC类 (同样是与GUI没有关联的),例如处理数组、 链表等数据结构的collection classes (CArray,CList)、与文件有关的CFile、 CStdioFile。 ? Console窗口将成为其标准输入和输出装置。 ? 以main函数为入口点。计算机科学与技术学院 张淼 99 第一个C++程序 - HelloWorld? 该程序在控制台输出一个字符串#include &iostream.h& void main() { cout&&&Hello World&&& }计算机科学与技术学院张淼100 第二个C++程序 - 还是HelloWorld? 该程序在控制台输出一个字符串#include &iostream& void main() { cout&&&Hello World&&& }计算机科学与技术学院张淼101 分析我们的Hello World? #include &iostream&? 预处理命令“#”?? 引用std名字空间计算机科学与技术学院张淼102 C++标准库包含了C语言和针对C++提供的新功能。 C标准库提供的头文件,在C++标准库中也提供了相 应的头文件,文件名的约定是:把C标准库头文件名的.h 去掉,然后在文件名前加一个字母c。 现在很多的C++实现为了保证与C语言的兼容性,往 往同时提供了两套头文件。值得注意的是:C++标准库 的程序实体是在名空间std中定义的,在C++程序,如果 包含的是相应的C++的头文件,则应通过名空间std来使 用这些功能。但注意:在VC++6.0的C++标准中,从C 标准包含进来的功能并没有在名空间std中定义。计算机科学与技术学院 张淼 103 ? void main()? 程序入口点? cout&&&Hello World&&&? cout:标准输出流对象,作用相当于printf ? && :插入符,将后面的内容插入到cout中, 即输出到屏幕上。 ? endl:end of line计算机科学与技术学院张淼104 输出? cout流输出? 格式? cout&&输出数据; ? 可以连续输出? cout&&a&&b&&c&&? 功能? cout可以输出字符、整数、浮点数和字符串 ? 类似printf函数计算机科学与技术学院张淼105 输入? cin流输入? cin:标准输入流对象,作用相当于scanf ? &&:提取符,将用户输入的内容保存到后面的 变量中。 ? 格式? cin&&输入数据; ? 可以连续输入(空白符:空格、横向制表符或回车 符作为输入数据之间的分隔符)? cin&&i&&j&&k;? 功能? 输入字符、整数、浮点数和字符串 ? 类似scanf函数计算机科学与技术学院 张淼 106 CH2.1? ? ? ? ? ?C++语言概述基本C++语法格式 数据类型 运算符和表达式 基本语句 函数 指针和引用计算机科学与技术学院张淼107 CH2.1.1 C++基本语法? C++是严格区分大小写的 ? C++是一种自由格式的语言用C++语言编程时,程序的书写非常自由,甚至可以把 整个函数体全部书写在一行上。但这样做,对人来说, 如果程序稍长一点,就难理解了。 书写基本原则如下: 一行一般写一条语句。长语句一行写不下时可以一条写 多行。分行原则是不能将一个单词分开。用双引号引用 的字符串和宏定义一行写不下需要续行时需用续行符\。 在书写C++程序时,一般采用比较美观的“缩进”格式 来书写。计算机科学与技术学院 张淼 108 ? C++程序的注释? 作用:提高程序的可读性;调试程序分类 C++型注释――双斜线“//”注释(从“//”开始,本行中所有字符都被 作为注释处理。)可以嵌在C型注释中。 C型注释――“/*”表示注释的开始,“*/”表示注释的结束。在“/*”、 “*/”之间的字符均被视作注释。主要用于大块注释。软件编码规范中说:“可读性第一,效率第 二”。在程序中必须包含适量的注释,以提高 程序的可读性和易维护性,程序注释一般占程 序代码总量的20%-50%。计算机科学与技术学院 张淼 109 ? C++中的标识符标识符是用来表示变量名、函数名、数组名、类名等 的有效字符序列。标识符命名要遵守合法性、有效性和易 读性原则。标识符的命名规则标识符的命名规则由字母、数字和下划线组成 以字母或下划线作为第一个字符, 其后跟零个或多个字母、数字、下划线。 正确的举例错误的sum Dram_ 1_peo //起始字符非法 rectangl operator //是关键字 大写字母与小写字母分别代表不同的标识符 e_myfri my $ //含有非法字符 end 不能与关键字相同计算机科学与技术学院 张淼 110 ? C++的关键字(参见书P2)计算机科学与技术学院张淼111 CH2.1.2 C++数据类型? 数据是程序处理的对象,在C++语言中, 所有的对象都属于某种数据类型。基本数据类型 指针 数据类型的分类 派生类型 引用复合类型(数组、类、结构 体、共用体、枚 举)计算机科学与技术学院张淼112 基本数据类型整型(int) 字符型(char)浮点型(实型)(float,double)逻辑型(布尔型)(bool)空值类型(void):用于函数和指针计算机科学与技术学院张淼113 常量在程序中,有些数据在运行期间是不允许改变的,我们称之为常量。字面常量 常量的两种 表示形式 符号常量程序中直接写出常量值的常量。计算机科学与技术学院张淼114 1. 整型常量 整型常量就是以文字形式出现的整数,包括三种形式。各种表示形式前均 可加上正或负号以表示它们值的正负,正号可以省略。形式 十进制 八进制组成由若干个0~9的数字组成,但 不能以0开头 以0开头,由若干0~7的数字组 成举例 1980,-50 010,-Fa -0X4Ab备注 L(或l)表 示长整型, U(或u)表 示无符号型, 如果后缀包 括L(或l) 和U(或u) 则表示无符 号长整型。十六进制 以0X或0x开头,由若干0~9的数字及A~F(大小写均可)的 字母组成计算机科学与技术学院张淼115 2. 实型常量 一般表示形式 指数表示形式实型常量只能用十进制表示,共有两种表示形式形式 一般 表示组成 又称小数表示形式。使用这种表示形 式时,实型常量由整数和小数两部分 组成。其中的一部分在实际使用时可 省略,但不允许两部分同时省去。举例 10.2, 10.,.2备注指数 表示默认数据类 型为double 型,如果加 上后缀F 表示很大或很小的实数,由尾数部分、 1.2E20,. (或f)则 字母E(或e)、指数部分三部分组成。 24e100, 为float型, 加上L(或l) 尾数部分的表示和一般表示形式相同, 则为long 指数部分必须是整数,但可正可负, double型。 当指数大于零时,正号可省。计算机科学与技术学院张淼116 3. 字符常量 字符常量通常是指用单引号括起来的一个字符,其数据类型是char。其 中单引号只是用来说明被它括起来的字符是字符常量,它本身不是字符常量 的内容。如:′a′,′#′,′G′。 C++语言中,还有一种转义序列的表示方法可用来表示字符常量。是用转义符号“\”后跟一 个字符或一个ASCII码来表 示一个单一字符。若“\” 后跟一个ASCII码,则表示 的是该ASCII码所代表的字 符。在这里ASCII码用八 进制或十六进制表示,这 里八进制和十六进制的表 示与前面表示整型常量的 方式不同,应无第一个 “0”。例如′\X62′就表 示字符′b′。117计算机科学与技术学院张淼 3. 字符常量在书写字符常量时,可显示字符通常用字符本身来书写, 而不可显示字符(控制字符)和有专门用途的字符用转 义序列表示。另外,对于下面的字符要特别注意:?反斜杠(\)应写成‘\\??单引号(‘)应写成‘\ ?? ?双引号(“)应写成‘\”?或 ‘”’计算机科学与技术学院张淼118 4. 字符串常量 字符串常量又称字符串或串常量,是用一对双引号括起来的字符序列。 例如:″xyz″, ″I am a student″,″This is a string″都是字符串。注由于双引号在字符串中用做定界符,所以,若字符串中需要出现 双引号时,则必须采用转义序列。C++语言中字符串的存储与字符不同,它在内存中的存放并不是简单地按 串中字符的顺序排放,而是在末尾加上一个′\0′,表示字符串的结束。 ″I″ I \0 字符串、字符及与其对应的存储形式 ′I′ I计算机科学与技术学院张淼119 字符串和宏定义一行写不下需要续行时需用续行符\。“this is a string!\ mnp”#define CONTAINING_RECORD(address, type, field) ((type *)( \ (PCHAR)(address) - \(UINT_PTR)(&((type *)0)-&field)))计算机科学与技术学院张淼120 符号常量符号常量是指有名字的变量。在程序 中使用常量时,除了采用字面常量形 式外,还可以首先通过常量定义给常 量取一个名字,并指定一个类型,然 后,在程序中通过常量名来使用这些 常量。计算机科学与技术学院张淼121 两种声明符号常量的方法用const声明符号常量 用#define声明符号常量解释 C++语言中广泛采用的声明符号常 C语言中声明符号常量的方法。 量的方法 其中#define是预处理指令。缺 点是不能显式声明常量的类型。 形式 const 数据类型 或: 数据类型 const 常量名=常量值; 常量名=常量值; #define pi 3.1415926正确 const double pi=3.1415926; 声明 错误 声明 pi=3.1415926; //错误 //错误最后不允许加 “;”计算机科学与技术学院张淼122 注意const定义的符号常量可以看作是一个 只读变量,不可在程序中修改它的值。 定义时必须初始化。bool类型的值true和false可以看成是C++语言预定义 的两个符号常量,它们的值分别为1和0。计算机科学与技术学院张淼123 变量有些数据在程序运行过程中是可以改变的,我们称之为变量。 一个变量对应着计算机中的一组内存单元,这组内存单元在 C++语言中用一个标识符来标识,即变量名。计算机科学与技术学院张淼124 一、变量的定义任何一个变量在被引用之前必须定义。与C语言不同的是 C++可以在程序中随时定义变量,不必集中在执行语句 之前。 定义格式:&类型& &变量名列表&;数据类型是指C++语言中的任一合法类型,每个变量都必须属于一种 类型。变量名的命名应遵照标识符的命名规则。在定义变量时,必须注意变量类型的选择。应该保证该变量 中将要存储的值不突破该变量类型所能表示的最大值。计算机科学与技术学院张淼125 二、变量的初始化程序中常需要对一些变量预先设置初值,这一过程称为初 始化。在C/C++中,可以在定义变量时同时使变量初始化。C++变量的初始化还有另外一种形式,它与C语言不同。例 如: int nX(1), nY(3);表示nX和nY是整型变量,它们的初值分别为1和3。计算机科学与技术学院张淼126 数组? 注意字符数组存储字符串 ? 数组的越界计算机科学与技术学院张淼127 结构体? 结构体是一种复合类型,结构体中可包含多 个类型不同的数据成员struct student { char name[10]; };? C++的结构体中允许有成员函数计算机科学与技术学院张淼128 共用体? 共用体是将多个数据成员组织为一个整体, 它们在内存中占用同一段存储单元union ab { };? C++的公用体中允许有成员函数计算机科学与技术学院张淼129 枚举类型? 枚举类型是将变量的值一一列举出来,变量 的值只限于列举出来的值的范围内enum weekday { sun,mon,tue,wed,thu,fri,sat };作用:增强程序代码的可读性。计算机科学与技术学院张淼130 用typedef定义类型使用关键字typedef可以将已有的类型名用新的类型名来代替。 格式: typedef &已有的类型名& &类型别名&;计算机科学与技术学院张淼131 CH2.1.3 运算符和表达式计算机科学与技术学院张淼132 运算符运算是指对数据的求值计算,如:加、减运算等。运算符给出了计算的 类型,而参与运算的数据叫操作数(变量、常量)。 一元运算符 运 算 符 的 分 类 需要1个操作数 需要2个操作数 需要3个操作数按所要求的操作数的多少二元运算符 三元运算符 算术运算符运算性质分关系运算符逻辑运算符…运算符具有优先级与结合性。计算机科学与技术学院 张淼133 当一个表达式中含有多个运算符时,先进行优先级高的运算, 后作优先级低的运算。如果表达式中出现了多个相同优先级 的运算时,运算的顺序就要看运算符的结合性了。 结合性是指当一个操作数左右两边的运算符优先级相同时, 按什么顺序进行运算,是自左向右,还是自右向左。计算机科学与技术学院张淼134 1、算术运算符C++语言中的算术运算符包括基本算术运算符和增1、减1运算符。 (1)基本算术运算符 一元运算符: +(取正)、-(取负) 二元运算符: +(或加)、-(或减)、*(乘)、/(除)、%(取余) 注意 1) 两个整数相除,将保留整数部分,不是四舍五入;进行浮点数除法,结 果是浮点型。如7/5.0、7.0/5、7.0/5.0的结果都是1.4。 2) 求余运算要求参与运算的两个操作数都是整型,其结果是两个数相除的 余数。例如40%5的结果是0,40%11的结果是7。要理解负值的求余运算,例 如40%-11结果是7,-40%11结果是-7,-40%-11结果也是-7。计算机科学与技术学院张淼135 (2)增1、减1运算符增1、减1运算符都是一元运算符,这两个运算符都有前置和后置两种形式。前置形式是指运算符在操作数的前面,后置是指运算符在操作数的后面。 例如: I++; --J; //++后置 //--前置注意注意:只能操作变量,不能操作常量。 前置和后置的区别。计算机科学与技术学院张淼136 操作数的类型转换类型转换方式 1). 隐含转换 如果两个操作数的类型不同,系统将自动地把其中操作数类型低的转换成 和另一个相同。 各种类型的高低顺序如下: int char、short unsigned long unsigned long double float 隐含转换 强制转换● char、short类型自动转换成int,float类型自动转换成double型。 ● 两个操作数中有一个为long double类型,另一个将也转换成long double 类型;否则,如果其中有一个为double类型,另一个将也转换成double 型;…,如上顺序从低向高转换。计算机科学与技术学院 张淼 137 隐式转换的方向就是将一个取值范围较小的类型向取值范围较大的类型转 换。它能确保在转换过程中数据不受损失。注类型的转换并不实际改变操作数的数据类型。它只是在计算表达式 值的时候,将操作数的值临时做了转换。计算后,操作数仍保持原有的 数据类型。计算机科学与技术学院张淼138 2). 强制类型转换强制类型转换的作用是将某种类型强制地转换成指定的类型。强制类型转换是通过强制转换运算符来实现的,具体表示形式如下: 类型说明符(操作数) 或 (类型说明符)操作数意义为把表达式的数据类型强制转换成类型说明符所指定的类型。计算机科学与技术学院张淼139 2、关系运算符C++语言中,关系运算符都是二元运算符,共有6个:&(小于)、 &(大于)、 &=(小于或等于)、&= (大于或等于)、== (等于)、!=(不等于)。 其比较的结果是一个bool型的值。当两个操作数满足关系运算符指定 的关系时,表达式的值为true,否则为false。true等于1,false等于0。 在C++编译系统中,任何不为0的数被认为是“真”,0被认为是 “假”。 应避免对浮点数进行==和!=比较运 算,如果需要,可采用判断两者的 差的绝对值是否小于某个很小的数 来实现。 x==y x!=y fabs(x-y)&1e-6 fabs(x-y)&1e-6张淼 140int i=-10;unsigned int j=1; i&j ?计算机科学与技术学院 3、逻辑运算符一元运算符: !(逻辑求反) 若其操作数为0(false),运算结果 为true(1),否则为false(0)。 二元运算符 &&(逻辑与) 只要两个操作数中有一个为0(false), 运算结果就为false(0),否则为true(1)。| |(逻辑或)只要两个操作数中有一个不为0(false), 运算结果为ture(1),否则为false(0)。短路求值:true || x false && x计算机科学与技术学院 张淼 141 4、位运算符一元运算符: ~(按位求反) 位运算符 二元运算符 &(按位与) | (按位或) ^(按位异或)&&(左移位) &&(右移位)位运算符是对其操作数按其二进制形式逐位进行运算,参与运算的操 作数应为整数。注位运算的结果就是位运算表达式的值,参与运算的操作数的值 并没有变化。张淼 142计算机科学与技术学院 5、sizeof运算符sizeof运算符用于计算某类型的数据占用的内存大小(字节数)。它是 一个一元运算符,操作数可以是C++语言中任一合法的数据类型。 该运算符的使用形式如下: sizeof(数据类型);sizeof(表达式);计算机科学与技术学院张淼143 6、赋值运算符?复合赋值10种复合赋值运算符:+=,-=,*=,/=,%=,&=,|=,^=,&&=,&&=注意:(1) 在复合赋值运算符之间不能有空格。 (2) 复合运算符的优先级和赋值符的优先级一样,在C/C++的所有运算符中只高 于逗号运算符,而且复合赋值运算符的结合性也是从右至左的。?多重赋值多重赋值是指在一个赋值表达式中出现两个或更多的赋值符(“=”) 例如:nNum1 = nNum2 = nNum3 = 100;当赋值操作的两个操作数类型不同时,编译程序将按赋值 转换规则进行隐式类型转换,即右边操作数转换成左边的 操作数类型。计算机科学与技术学院 张淼 144 7、条件运算符唯一的三目运算符是条件运算符。格式:&条件表达式& ? &表达式1& :&表达式2&计算机科学与技术学院张淼145 8、逗号运算符逗号运算符是优先级最低的运算符,它可以使多个表 达式放在一行上。计算时,从左至右逐个计算每个表 达式,最终整个表达式的结果是最后计算的那个表达 式的类型和值。例如: j = ( i = 12 , i + 8); 式中,i = 12 ,i + 8 是含逗号运算符的表达 式,计算次序是先计算表达式i = 12,然后再计算i + 8,整个表达式的值是最后一个表达式的值,即i + 8的值20, 从而j的结果是20。计算机科学与技术学院张淼146 CH2.1.4 基本语句计算机科学与技术学院张淼147 语句可用于计算表达式的值、控制程序执行的顺序,有时语句也可能不作 任何操作(空语句)。表达式语句 转移语句 简单语句 空语句 分类 复合语句goto语句 break语句 continue语句 return语句结构语句if语句 选择语句 switch语句 while语句 循环语句 do-while语句 for语句148计算机科学与技术学院张淼 CH2.1.5 函数函数是一个能完成某一独立功能的子程序,也就是程序模 块。每个C++程序至少包含一个函数,即main函数(主函数)。 在面向过程的程序设计中,一个较为复杂的程序一般通过模块 化,分解成主模块与若干子模块的组合,即一个主函数与若干 子函数。程序是以函数为单位,由一个或多个函数组成的。 在面向对象的程序设计中,一个C++程序是由类的实例 (对象)构成。函数主要用于定义对象的操作接口。 本部分介绍有关函数的一些基本知识,如:函数的定义及 调用等。这些知识虽然大部分是建立在面向过程的程序设计方 法的基础上,但它们也是我们学习面向对象程序设计的基础。计算机科学与技术学院张淼149 在面向过程的程序设计中,一个C++程序由一个或 多个函数组成。当程序开始运行时,系统自动调用主 函数。主函数可以调用子函数,子函数还可以调用其 他子函数。调用其他函数的函数称为主调函数,被其他函数调用 的函数称为被调函数。计算机科学与技术学院张淼150 计算机科学与技术学院张淼151 函数的定义在C++程序中,定义一个函数的格式如下: 类型 函数名(形式参数表)该函数的类型,即该 函数返回值的类型。{ 语句序列 }函数体:可以有0条、1条或多条语 句。当是0条语句时,该函数称作空 函数。计算机科学与技术学院张淼152 每个函数都有类型,如果没有明确指定,则类型为int。函数的返回值是需要返回给主调函数处理的结果,由return语句给出。当 该函数没有返回值时,函数的类型为void,可不写return语句。 return语句的一般格式如下: return 表达式; 注 对于没有返回值的函数,return语句可有可无。 没有return语句:函数在被调用时,程序执行完函数体的最后 一条语句后,自动返回主调函数。 有return语句: 这时的return语句应表示为: return;情况分类一个函数中允许出现多个return语句,分别用于不同条件下的函数返回。计算机科学与技术学院 张淼 153 形式参数表由0个、1个或多个参数组成,内容如下: 类型1 形式参数名1,类型2 形式参数名2,…,类型n 形式参数名n 说明了对应形式参 数的数据类型。 是一个标识符。形式参数又称形参,将函数需要处理的数据、影响函数功能的因素和函数 处理的结果作为形参,实现主调函数与被调函数之间的联系。没有形参的 函数,可以在形参表的位置填上void或保留空白,但形参表两边的圆括号 不可省略。计算机科学与技术学院张淼154 函数的定义double rectanglearea(double a,double b) { s=a*b; }计算机科学与技术学院张淼155 每个函数都是一个功能独立的模块,绝对不允 许在一个函数体内定义另一个函数。计算机科学与技术学院张淼156 函数的声明声明函数,一般采用声明函数原型。 形式如下: 类型 函数名(形式参数表); 必须以分号结尾。函数原型中的类型、函数名和形参表必须与定义该函数时完全一致,但函 数原型中可以不包含参数名,而只包含形参的类型。例如:double rectanglearea(double a,double b) ; double rectanglearea(double ,double);计算机科学与技术学院张淼157 函数的调用除主函数main由系统自动调用外,其他函数都由主函数直接或间接调用的。函数的调用的一般形式如下: 函数名(实际参数表)程序中调用的所有函数都要有定义,如果函数定义在其 他文件中(如C++的标准库)或定义在本源文件使用点 之后,则在调用前需要对被调用的函数进行声明。计算机科学与技术学院张淼158 main( ) ① ⑦ 结束 ⑥ ② 调fun( )保存: 返回地址 当前现场③fun( )④恢复: 主调程序现场 返回地址⑤返回计算机科学与技术学院张淼159 函数调用时,如果被调用函数带有形参,系统需要首先给它的形 参分配内存空间,并用调用表达式中的实参初始化形参。函数调用时的参数传递指的就是实参与形参结合过程。 传值调用: 实参与形参结合方法 传址调用 引用调用 使用值调用时,系统首先为形参分配内存空间,并将实参的值按位置一 一对应赋给形参。在被调用函数中形参值的任何改变都不会影响到实参。 简称值调用(默认)。计算机科学与技术学院张淼160 主调函数: AD = power(A,3)2.53X2.5N3被调函数: double power(double X, int N)计算机科学与技术学院 张淼 161 例:输入两 整数交换后输出#include&iostream.h& void Swap(int a, int b); int main( ) { int x(5), y(10); cout&&&x=&&&x&&& y=&&&y&& Swap(x,y); cout&&&x=&&&x&&& y=&&&y&& return 0; }计算机科学与技术学院 张淼 162 void Swap(int a, int b) { t=a; a=b; b=t; }运行结果: x=5 x=5计算机科学与技术学院 张淼y=10 y=10163 数组作为函数参数? 数组元素作实参,与单个变量一样。 ? 数组名作参数,形、实参数都应是数组名, 类型要一样,传送的是数组首地址。对形参 数组的改变会直接影响到实参数组。计算机科学与技术学院张淼164 嵌套调用main{} ① 调fun1() ⑨ 结束②⑧fun1( ) ③ ④ 调fun2() ⑦ ⑥ 返回fun2( ) ⑤ 返回计算机科学与技术学院张淼165 例 输入两个整数,求平方和。#include &iostream.h& void main(void) { int a,b; int fun1(int x,int y); cin&&a&&b; cout&&&a 、 b 的 平 方 和 : & &&fun1(a,b)&& }计算机科学与技术学院 张淼 166 int fun1(int x,int y) { int fun2(int m); return (fun2(x)+fun2(y)); } int fun2(int m) { return (m*m); } 运行结果: 3 4 a、b的平方和:25计算机科学与技术学院 张淼 167 递归调用?函数直接或间接地调用自身,称为递归调用。 ?递归过程的两个阶段:?递推: 4!=4×3! → 3!=3×2! → 2!=2×1! → 1!=1×0! → 0!=1 未知 已知 ?回归: 4!=4×3!=24←3!=3×2!=6←2!=2×1!=2←1!=1×0!=1←0!=1 未知 已知计算机科学与技术学院张淼168 例求n!分析:计算n!的公式如下:这是一个递归形式的公式,应该用递归 函数实现。计算机科学与技术学院张淼169 #include &iostream.h& long fac(int n) { if (n&0) cout&&&n&0,data error!&&& else if (n==0) f=1; else f=fac(n-1)*n; return(f); }计算机科学与技术学院 张淼 170 void main( ) { long fac(int n); cout&&&Enter a positive integer:&; cin&&n; y=fac(n); cout&&n&&&!=&&&y&& }运行结果: Enter a positive integer:8 8!=40320计算机科学与技术学院 张淼 171 程序的执行过程中,调用函数时先要保存主调函 数的现场和返回地址,然后程序转移到被调函数 的起始地址继续执行。被调函数执行结束后,先 恢复主调函数的现场,取出返回地址并将返回值 赋给函数调用本身,最后在返回地址处开始继续 执行。当函数体比较小时,且执行的功能比较简 单时,这种函数调用方式的系统开销相对较大。计算机科学与技术学院张淼172 内联函数在程序编译时,编译系统将程序中出现内联函 数调用的地方用函数体进行替换。由于在编译 时将函数体中的代码被替代到程序中,因此会 增加目标程序代码量,进而增加空间开销,而 在时间开销上不象函数调用时那么大,可见它 是以目标代码的增加为代价来换取时间的节省。注内联函数的使用会增加程序的代码量。内联函数一般来说仅适用于只有一、两条语句的小函数。计算机科学与技术学院 张淼 173 内联函数的定义:在函数定义时,在函数的类型前增加关 键字inline。形式如下: inline 类型 函数名(形参 表) 说明:仅在声明函数原型时加 { 上关键字inline,并不能达到 ......//函数体 内联效果。 }计算机科学与技术学院张淼174 #include&iostream.h& inline double CalArea(double radius) { return 3.14*radius* } int main( ) { double r(3.0); area=CalArea(r); cout&&area&& return 0; }计算机科学与技术学院张淼175 注(1) 内联函数的定义必须出现在内联函数第一次 被调用之前。内联函数只能先定义后使用,不存 在先声明再使用。 (2) 内联函数名具有文件作用域 ,在一个文件中 定义的内联函数对于另一个文件是不可见的,因 此调用内联函数时一定要见到内联函数的定义。 对于一个多文件结构的程序,如果在一个源文件 中定义了一个内联函数,而在另一个源文件中对 其声明并使用,这将导致程序连接时刻的错误。计算机科学与技术学院张淼176 ? 在一个函数中,要求通过函数来实现一种不 太复杂的功能,并且要求加快执行速度,选 用( )合适。 A. 内联函数 B. 重载函数 C. 递归调用 D. 嵌套调用计算机科学与技术学院张淼177 注(3) 需要定义成的内联函数不能含有循环、switch 和复杂嵌套的if语句。 (4) 递归函数是不能被用来做内联函数的。(5) 把成员函数的定义放在类定义中是建议编译程 序按内联函数处理它们。编译器是否将用户定义成的内联函数作为真正 的内联函数处理由它自行决定。计算机科学与技术学院张淼178 全局变量与局部变量在C++中,根据变量的定义位置, 把变量分为全局变量和局部变量。全局变 量是指定义在函数外部的变量,它能被所 有函数使用。局部变量是指在复合语句 (函数)中定义的变量,它们只能在定义 它们的复合语句(包括内层的复合语句) 中使用。计算机科学与技术学院张淼179 计算机科学与技术学院张淼180 全局变量可以定义在函数外的任何地方,如果在 使用一个全局变量时未见到它的定义,则在使用 前需要对该全局变量进行声明。 变量声明格式:extern &类型名& &变量名&; ?变量定义要给变量分配空间,变量声明则否。?在整个程序中,一个变量的定义只有一个,而该 变量的声明可以有多个。计算机科学与技术学院 张淼 181 局部变量也可以放在复合语句的任何位置,但是, 在复合语句中局部变量定义 之前不能使用他们。 int main(){…x… //error //ok…x…}计算机科学与技术学院 张淼 182 函数的形参也可看成局部变量,它们 只能在相应的函数中使用。计算机科学与技术学院张淼183 变量的存储分配(生存期)变量是内存空间的一种抽象,程序中定义的每个 变量在程序运行时刻都有与之对应的内存空间。 但是,何时给变量分配空间以及相应空间分配在 哪里?这要视变量的性质而定。通常把程序运行 时一个变量占有内存空间的时间段称为该变量的 生存期。计算机科学与技术学院张淼184 变量的三种生存期静态 内存空间从程序开始执行就进行分配,直到程序结 束才收回。全局变量具有静态生存期。 自动 内存空间在程序执行到它们所在的复合语句(函 数)时才分配,当定义它们的复合语句执行结束时, 它们的空间将会收回。局部变量和函数的参数一般 具有自动生存期。 动态 内存空间用new操作分配、用delete操作收回。计算机科学与技术学院 张淼 185 另外,在定义局部变量时,可以为它们加上存储类型 修饰符auto、static或register来指定它们的生存期。 局部变量的默认存储类型为auto,即定义局部变量时, 如果未指定存储类,则其存储类为auto。定义为auto存储 类的局部变量具有自动生存期;定义为static存储类的局部 变量具有静态生存期;定义为register存储类的局部变量也 具有自动生存期。它与auto存储类的局部变量的区别是: register存储类是建议编译程序把相应的局部变量的空间分 配在CPU的寄存器中,目的是为了提高对局部变量的访问效 率。 static存储类的局部变量的作用是它能在函数调用时获 得上次调用结束时该局部变量的值。计算机科学与技术学院 张淼 186 #include &iostream.h&int z=0; void f(){int x=0;static int y=0; x++;void main(){f(); z++; f(); }y++;z++;cout&&“x=“&&x&&“,y=”&&y &&“,z=”&&z&&}计算机科学与技术学院张淼187 当一个程序准备运行时, 操作系统将为其分配一块 内存空间,其中包括四个 部分:静态数据区 (static code)、代码 区(code)、栈区 (stack)和堆区(heap , 或称自由存储区,free store)。计算机科学与技术学院 张淼静态数据区 代码区 栈区 堆区程序内存分配示意图188 静态数据区用于全局变量、static存储类的局部变量以 及常量的内存分配。 代码区用于存放程序的指令,对C++程序而言,代码区 存放的是所有函数代码;栈区用于auto存储类的局部变量、函数的形式参数以 及函数调用时的有关信息(如函数返回地址等)的内存 分配; 堆区用于动态变量的内存分配。静态数据区 代码区 栈区 堆区计算机科学与技术学院张淼189 ? 全局变量、static存储类的局部变量(存放在 静态数据区的变量)在变量定义时有默认值。 int型为0,浮点型为0.0,char型为空。 ? auto存储类的局部变量在定义时没有值,此时 是一个不可预料的值,因此我们必须在使用前 对它进行赋值或初始化。计算机科学与技术学院张淼190 全局变量,是在main()函数执行前就分配好了的。 其实,在main()函数中的显示代码执行之前,会 调用一个由编译器生成的_main()函数,而 _main()函数会进行所有全局变量的构造及初始 化工作。而在main()函数结束之前,会调用由编 译器生成的exit函数,来释放所有的全局变量。 比如下面的代码:计算机科学与技术学院张淼191 void main(void) { … …// 显式代码 }void main(void) { _main(); //隐式代码,由编译器 产生,用以构造所有全局变量 … … // 显式代码 …… exit() ; // 隐式代码,由编译器产 生,用以释放所有全局变量}计算机科学与技术学院 张淼 192 C++程序的多模块结构逻辑上,一个C++程序由一些全局函数(区别于类 定义中的成员函数)、全局常量、全局变量/对象以及类 的定义构成,其中必须有且仅有一个main的全局函数。 函数内部还可以包含形参、局部常量、局部变量/对象的 定义以及语句。 C++函数内部不能再定义函数。计算机科学与技术学院张淼193 为了便于组织、管理和理解C++程序,在物理上我们通常 可以按照某种规则对构成C++程序的若干逻辑单位(全局 函数、全局常量、全局变量/对象、类等)进行分组,分别 把它们放到若干源文件中。编译程序对每个源文件分别进行 编译。 分组的原则是按照模块进行,一个模块一般包含两部分:接 口和实现。接口给出在本模块中定义的、提供给其他模块使 用的一些程序实体(如函数、全局变量等)的声明;模块的 实现给出了模块中实体的定义。 在C++中,一个模块通常由两个源文件构成,一个是.h文 件,用于存放模块接口的定义;另一个是.cpp文件用于存 放模块的实现。在一个模块中要用到另一个模块中定义的程 序实体时,需要在前者的.cpp文件中用文件包含命令把后 者的.h文件包含进来。计算机科学与技术学院 张淼 194 编译预处理命令――文件包含在编译前,用命令中的文件名所指定的文件内容替换该命令。 #include &文件名& #include “文件名” &&在系统指定的目录下寻找指定文件;“”先在包含#include命令的源文件所在目录下查找指定 文件,然后再在系统指定的目录下寻找指定的文件。计算机科学与技术学院张淼195 VC++程序编译链接原理与过程Animal.h #include Animal.cpp 预处理 翻译单元1 编译 (Compile) Animal.obj Fish.obj main.obj 翻译单元2 翻译单元3 Fish.h #include Fish.cpp main.cpp链接 (Link) .exe 可执行文件计算机科学与技术学院 张淼.lib C++的标准库函数 标准类库196 标识符的作用域C++根据程序的结构和标识符定义的位置,为每一 个定义了的标识符规定了一个作用域。标识符的作用域 是指一个定义了标识符的有效范围,即该标识符所标识 的程序实体能被访问的程序段。 C++把标识符的作用域分成若干类,其中包括:局 部作用域、全局作用域、文件作用域、函数作用域、函 数原型作用域、类作用域和名空间作用域。当标识符的作用域完全相同时, 不允许出现相同的标识符名。而 当标识符具有不同的作用域时, 允许标识符同名。计算机科学与技术学院 张淼 197 局部作用域(块作用域)局部作用域指在函数定义或复合语句中,从 标识符的定义点开始到函数定义或复合语句结束 之间的程序段。 C++中的局部常量名、局部变量名/对象 名以及函数的形参名具有局部作用域。计算机科学与技术学院张淼198 局部实体定义前可以有语句,但这些语句 不在相应标识符的作用域内,从而不能使用后 面定义的标识符。 如果一个标识符的局部作用域中包含其它 复合语句(内层复合语句),并且在该内层复 合语句中定义了一个同名的不同实体,则外层 定义的标识符的作用域应该是从其作用域中扣 除内层同名标识符的作用域之后得到的作用域。计算机科学与技术学院张淼199 全局作用域全局作用域指构成C++程序的所有源 文件,具有全局作用域的标识符称为全局 标识符。 全局变量名/对象名、全局函数名和全 局类名的作用域一般具有全局作用域。它 们在整个程序中可用。计算机科学与技术学院张淼200 如果某个局部作用域中定义了与某个全局标 识符同名的标识符,则该全局标识符的作用域应 扣掉与之同名的局部标识符作用域。 在局部标识符的作用域中若要使用与其同名 的全局标识符,则需要用全局选择符(::)对全 局标识符进行修饰(受限)。计算机科学与技术学院张淼201 使用全局标识符时,若该标识符的定义点在其他 源文件中或在本源文件中使用点之后,则在使用 前需要声明它。 通常,把全局标识符的声明放在某个.h文件中, 在需要使用这些全局标识符的源文件中用 #include编译预处理命令把声明文件包含进 来。计算机科学与技术学院张淼202 文件作用域文件作用域指单独的源文件。在全局标识符的定义中加上static修饰符, 则该全局标识符就成了具有文件作用域的标识符, 它们只能在定义它们的源文件中使用。在函数外用const定义的常量名具有文件 作用域。 用编译预处理命令#define定义的标识符 不属于作用域要考虑的范畴,因为它们在编译 前将被替换成所定义的内容。计算机科学与技术学院 张淼 203 C++中的关键词static有两个不 同的含义。在局部变量的定义中, static修饰符用于指定局部变量 采用静态存储分配;而在全局标 识符的定义中,static修饰符用 于把全局标识符的作用域改为文 件作用域。计算机科学与技术学院张淼204 函数作用域函数作用域是指由整个函数定义所构成的程 序段。语句标号是唯一具有函数作用域的标识符, 可以在定义它们的函数体的任何地方访问它们。计算机科学与技术学院张淼205 函数作用域与局部作用域的区别 函数作用域包括整个函数,而局部作用域是 从定义点开始到函数定义或复合语句结束。在函数体中一个语句标号只能定义一次,即 使在内层的复合语句中,也不能再定义与外层 相同的语句标号。 C++把语句标号作为一种特殊的标识符看待, 它与其他种类的标识符属于不同的范畴,因此, 语句标号的作用域可以和同名的其它标识符的 作用域重叠。计算机科学与技术学院张淼206 函数原型作用域函数原型作用域是指用于函数声明的函数原型, 其中的形参名(如果给出)的作用域从函数原型 开始到函数原型结束,即在函数原型声明中的左、 右括号之间。在函数原型中声明的标识符可以与函数定 义中说明的标识符名称不同。计算机科学与技术学院张淼207 下列的标识符中,( 函数作用域的。 A. 函数形参 B. 语句标号 C. 外部静态类标识符 D. 自动类标识符)是计算机科学与技术学院张淼208 file1.cpp void f() {… 实现打印 }file2.cpp void f() {… 实现屏幕输出 }Main.cpp int main() { f(); 实现打印 f(); 实现屏幕输出 }计算机科学与技术学院 张淼 209 名空间(namespace)名空间是给一组程序实体的定义取一个名字使之构成一个作 用域――名空间作用域。namespace A {int x=1;void f(){… }void g(){… }}计算机科学与技术学院 张淼 210 在一个名空间中定义的全局标识符,其作用域为该名空 间。当在一个名空间外部需要使用该名空间中定义的全 局标识符时,可用该名空间的名字来修饰或受限。 如:A::f(); 当使用某个名空间上的程序实体时,如果这些程序实 体的名与其它全局程序实体的名不冲突,则可在使用 前写一个using &名空间&指示项,使得今后使用相 应名空间中的程序实体时不必用空间名受限。计算机科学与技术学院张淼211 题目:以某种进制形式输出整数。 void print(int value,int base); print(x,10);print(x,2);计算机科学与技术学院张淼212 带默认形参值的函数在C++中,允许在定义或声明函数时,为函 数的某些参数指定默认值。当调用这些函数时 没有提供相应的实参时,则相应的形参采用指 定的默认值,否则相应的形参采用调用者提供 的实参值。void print(int value,int base=10);print(x);print(x,2);计算机科学与技术学院 张淼 213 int add(int x=5,int y=6) { return x+y; }void main(void) { add(10,20); //10+20 add(10); //10+6 add( ); //5+6 }计算机科学与技术学院 张淼 214 ? 一个函数中有多个默认参数时,则形参分布中, 默认参数应从右到左逐渐定义(所有默认参数 必须放在参数表的最后,即在一个指定了默认 值的参数的右边,不能出现没有指定默认值的 参数)。计算机科学与技术学院张淼215 int add(int x,int y=5,int z=6); //正确 int add(int x=1,int y=5,int z); //错误 int add(int x=1,int y,int z=6); //错误计算机科学与技术学院张淼216 ? 在相同的作用域内,缺省形参值的声明应保 持唯一,但如果在不同的作用域内,允许说 明不同的缺省形参。计算机科学与技术学院张淼217 int add(int x=1,int y=2);void main(void) { int add(int x=3,int y=4); add( ); //使用局部缺省形参值(实现3+4) } void fun(void){ ...add( ); //使用全局缺省形参值(实现1+2) }计算机科学与技术学院张淼218 //file.cppvoid f(int a,int b,int c) //函数f的定义 {…} //file1.cpp void f(int a,int b,int c=2); …//file2.cppvoid f(int a,int b=1,int c=0) ; …计算机科学与技术学院 张淼 219 函数重载? C++允许功能相近的函数在相同的作用域 内以相同函数名声明,从而形成重载。方便 使用,便于记忆。 ? 重载的要求:形参的个数不同或类型不同。int add(int x, int y); float add(float x, float y); int add(int x, int y); int add(int x, int y, int z);计算机科学与技术学院 张淼形参类型不同形参个数不同220 重载函数的返回类型,即函数类型可以相同,也可以不同。如果仅仅是返 回类型不同,而函数名相同、形参表也相同,则是非法的。例如: int fun(int a,int b); long fun(int a,int b); 例如: int fun(int a,int b); int fun(int x,int y);不合法的 说明:合法的。但不是重载。它只是对同 一函数原型的多次声明。函数重载又称函数的多态性。它通过改变形参的个数或类型使多个函数共 用一个函数名。计算机科学与技术学院张淼221 当重载的函数带有默认参数时,应该注意避免二义性。例如: int fun(int a,int b=0); int fun(int a);说明:遇到fun(2)的函数调用时,编译 器将无法准确地确定应调用哪个函数。计算机科学与技术学院张淼222 下面的函数声明中, ( )是” void max(int a, int b);”的重载函数? A.int max(int a, int b) ; B.void max(int a, char b) ; C.float max (int a, int b, int c=0) ; D.void max (int a, int b=0) ;计算机科学与技术学院张淼223 C++语言的系统函数定义:C++编译系统本身定义了几百个在编程时可能经常用到的函数。 在使用某一系统函数前需要知道它的函数原型在哪个头文件中。这也可以 通过库函数手册或联机帮助查到。在使用某个系统函数前所需要做的就是 用include指令在程序中嵌入相应的头文件,然后便可以和调用自己定义的 函数一样使用系统函数。计算机科学与技术学院张淼224 CH2.1.6指针和引用计算机科学与技术学院张淼225 指针? 指针变量的定义&类型& *&指针变量名1&[,*&指针变量名2&,...]? 类型为指针所指向的变量的类型,即指针类 型。指针类型不是指针本身数据值的类型, 任何一个指针本身的数据值都是unsigned long int型。计算机科学与技术学院张淼226 变量的地址取地址符&来获得一个变量的地址。 对于数组和函数,它们的内存首地址可以不用&来获得, 数组变量名和函数名本身就表示它们在内存中的首地址。 对于常量0,它除了表示一个整型常量外,还可以 表示一个空指针。 空指针不代表任何内存空间的地址,它属于所有 的指针类型。 在C++的标准头文件cstdio或stdio.h中,定义 了一个符号常量NULL,用于表示空指针。计算机科学与技术学院 张淼 227 指针赋值? 对于一个指针变量只能把在定义该指针变量 时所指定类型的变量的地址赋给它。 ? 在使用指针变量前,一定要对其进行初始化 或使其有确定的地址数值。 ? 任何类型的指针都可以赋给void *类型的指 针。计算机科学与技术学院张淼228 间接访问操作*与-&? 对于一个指针变量可以通过间接访问操作符 *来访问它所指向的变量。 ? 对于一个指向结构体类型变量的指针,如果 通过该指针变量来访问相应结构体变量的成 员,则可写成: 指针变量-&结构成员 (*指针变量).结构成员计算机科学与技术学院张淼229 指针的输出? 指针输出操作有一个例外:当输出字符指针 (char *)时,输出的不是指针值,而是该 指针所指向的字符串。 char str[]=“ABCD”; char *p= cout&&p;//输出:ABCD cout&&*p;//输出:A计算机科学与技术学院张淼230 指针作为形参类型――地址调用? 把指针作为形参的类型可以产生两个效果:? 提高参数传递效率。 ? 通过形参改变实参的值。? 指向常量的指针? const &类型& *&指针变量&; ? const的含义是不能改变&指针变量&所指向的 数据的值。 ? 指向常量的指针变量可以指向const常量也可指 向变量,只不过不能通过它来改变所指向的变 量值而已。 ? 对于一个指向变量的指针变量,不允许它指向 一个常量。计算机科学与技术学院 张淼 231 const int *p; p=&x; *p=1; // p=&y; *p=1;//error Y=1;//ok计算机科学与技术学院 张淼 232 const int x=0; int *p; p=&x;//error计算机科学与技术学院张淼233 ? 不要将指向常量的指针类型与指针类型的常量 混淆了。 指针类型的常量必须初始化。 int x,y; int *const p=&x; *p=1; p=&y;//错误,p是一个常量其值不能改变。计算机科学与技术学院张淼234 int a=0; const int *p;说明( A.不能修改p指针 的值 。 B.不能通过p修改p所指向的变量的值。 C.p=&a;是错误的。 D.上述B、C二者。)。计算机科学与技术学院张淼235 ? 已知 int *const p=&x;执行语句 *p=1;会发生错误。 ( ) ? Windows API中的所有函数都包含在DLL 中。 ( )计算机科学与技术学院张淼236 函数指针与返回指针值的函数? 函数指针:C++中可以定义一个指针变量,使它指 向一个函数。 &返回类型& (*&指针变量&)(&形式参数表&) double (*f)(int); ? 返回指针值的函数:返回值类型是一个指针类型。 int *max(const int x[],int num) { …… }计算机科学与技术学院 张淼 237 指针和数组计算机科学与技术学院张淼238 指针与动态变量动态变量:从静态的程序中无法确定它们的存在, 只有当程序运行起来,随着程序的运行,它们根 据程序的需要动态产生和消亡。其内存分配在堆 区。动态变量没有名字,因此对动态变量的访问 需要通过指向动态变量的指针变量来进行。计算机科学与技术学院张淼239 动态变量的创建? ? ? ? new 类型(初值); new 类型[第1维的大小]…[第n维的大小]; void *malloc(unsigned int size); 例: ? int *p= *p=1; ? int *p=new int(100); ? char *p=new char[10]; ? int (*q)[4]=new int[5][4]; ? int *p=(int *)malloc(sizeof(int));计算机科学与技术学院张淼240 动态变量的撤消? 在C++程序运行期间,动态变量不会自动消亡,在一 个函数调用中创建的动态变量,函数返回后仍然存在 (可以使用)。如果不再需要这个动态变量了,则应该 显式使之消亡。? 用delete释放用new动态分配的内存空间? delete 指针变量 ? delete[] 指针变量? 用free释放用malloc动态分配的内存空间? void free(void *p)? 注意事项? new和delete应成对出现,malloc和free成对出现计算机科学与技术学院张淼241 new和delete示例? 开辟空间用来存放结构体变量#include &string.h& struct student { char name[10]; }; void main() { student *p = strcpy(p-&name,&张三&); p-&num = 10123; p-&age = 20; }计算机科学与技术学院 张淼 242 new和malloc比较? 使用方便性? malloc需要计算内存空间大小,通常需要与 sizeof函数配合使用 ? malloc的返回值为void*,赋值给某一类型的 变量时需要进行强制类型转换? student *s = (student *)malloc(sizeof(student));? new运算符自动计算内存空间大小,而且返回 的就是具体的数据类型,不需要进行转换? 程序执行效率? new和delete是运算符,执行效率高 ? malloc和free是函数,执行效率相对较低计算机科学与技术学院 张淼 243 用delete或 free撤消动态变量后,C++编译程序一般不 会把指向它的指针变量的值赋为 NULL,这时就会出现 “悬浮指针”(dangling pointer),它指向一个无效空 间。这时如果再通过这个“悬浮指针”来使用相应的 动态变量会导致程序的语义错误。 对于一个动态变量,如果没有撤消它,而仅仅是把指 向它的指针变量指向了别处,或指向它的指针变量的 生存期结束了,这个动态变量就会变成一个“孤儿”, 这种现象称为内存泄露。程序中再也访问不到它,而 它却一直占据内存空间,从而导致内存空间的浪费。计算机科学与技术学院张淼244 2…p2000void f() {int *p=new int(2);…… }计算机科学与技术学院 张淼栈内存堆内存245 下面程序中的变量p,数字2,变量a,b,c分别 被分配在( )内存区。 //xxx.cpp #include &iostream.h& static int c=5; void f() { int *p=new int(2);} void main() { static int a=0; int b=3; f(); cout&&a&&b&&c&& }计算机科学与技术学院 张淼 246 A. c为静态数据区;a,b,p为栈区,2为堆 区 B. c为静态数据区;a,b为栈区,2,p为堆 区 C. a,c为静态数据区; b为栈区,2,p为堆 区 D. a,c为静态数据区;p,b为栈区,2为堆 区计算机科学与技术学院张淼247 引用? 什么是引用?? 引用是C++中针对变量的一种别名机制 ? 引用不能单独存在,它的存在的前提是它所代 表的变量首先存在? 引用定义? 类型 &引用 = 变量名? 定义一个引用? 例如: int& b =计算机科学与技术学院 张淼 248 计算机科学与技术学院张淼249 引用示例? 定义引用并使用引用#include &iostream& void main() { int a = 50; int& b = a = 100; cout&&&a=&&&a&& cout&&&b=&&&b&& }计算机科学与技术学院 张淼 250 引用的限制? 引用不能单独使用,必须进行初始化。 ? int& //错误,没有初始化引用? 引用变量定义后,它不能再引用其它变量? 当引用类型变量的初始化值是常数时,则必须将 该引用定义成const类型。 ? int const a = 50; ? const int& b =计算机科学与技术学院张淼251 ? 引用与其所引用的变量必须具有相同的类型 ? int a = 50; ? float& b = //错误,引用与变 量类型不一致 ? 可以对指针引用,因为指针也是变量 ? int a = 50; ? int* b = &a; ? int*& c = //c是对指针变量b 的引用计算机科学与技术学院张淼252 函数的参数传递(1)? 值传递void swap(int a,int b) { temp = a = b = } void main() { int m = 3,n = 5; swap(m,n); cout&&&m=&&&m&&& n=&&&n&& }计算机科学与技术学院 张淼 253 函数的参数传递(2)? 地址传递void swap(int *a,int *b) { temp = *a; *a = *b; *b = } void main() { int m = 3,n = 5; swap(&m,&n); cout&&&m=&&&m&&& n=&&&n&& }计算机科学与技术学院 张淼 254 函数的参数传递(3)? 引用传递void swap(int& a,int& b) { temp = a = b = } void main() { int m = 3,n = 5; swap(m,n); cout&&&m=&&&m&&& n=&&&n&& }计算机科学与技术学院 张淼 255 void f(const int& x) { …; } void main() { int a = 3; f(a); }计算机科学与技术学院张淼256 引用作为函数返回值类型int &max(int x[],int num) {int i,j; j=0; for(i=1;i&i++) if(x[i]&x[j]) j=i; return x[j]; } …… int a[10]; …… cout&&max(a,10)&& max(a,10)+=1;计算机科学与技术学院 张淼 257 CH2.2 C++面向对象程序设计基础面向对象程序设计模拟自然界认识和处 理事物的方法,将数据和对数据的操作 方法放在一起,形成一个相对独立的整 体――对象(object)[面向对象的程 序设计就是由这些对象构造程序],同 类对象还可抽象出共性,形成类 (class )。一个类中的数据通常只能 通过本类提供的方法进行处理,这些方 法成为该类与外部的接口。对象之间通 过消息(message)进行通讯。计算机科学与技术学院 张淼 258 在面向过程的程序设计方法中,问题被看作一系列将 被完成的任务,如读、计算和打印。许多函数用于完 成这些任务。问题的焦点集中于函数。计算机科学与技术学院张淼259 面向过程程序设计的基本任务是编写计算机执 行的指令序列,并把这些指令以函数的方式组织起 来。通常我们使用流程图组织这些行为 (action),并描述从一个行为到另一个行为的 控制流。 当我们集中精力开发函数的时候,很少会去注 意那些被多个函数使用的数据(data)。在这些 数据身上发生了什么事情?那些使用这些数据的函 数又对它们产生了什么影响? 在多函数(multi-function)程序中,许多 重要的数据被放置在全局数据区,这样它们可以被 所有的函数访问。每个函数都可以具有它们自己的 局部数据。计算机科学与技术学院 张淼 260 计算机科学与技术学院张淼261 面向对象程序设计方法的主要出发点是弥补 面向过程程序设计方法中的一些缺点。面向对象 的设计思想力图使在计算机语言中对事物的描述 与现实世界中该事物的本来面目尽可能地一致。 OOP把数据看作程序开发中的基本元素,并且不 允许它们在系统中自由流动。它将数据和操作这 些数据的函数紧密的连结在一起,并保护数据不 会被外界的函数意外的改变。OOP允许我们将问 题分解为一系列实体――这些实体被称为对象 (object),然后围绕这些实体建立数据和函 数。计算机科学与技术学院 张淼 262 计算机科学与技术学院张淼263 面向对象的程序设计1基本概念2 “面向对象”程序设计的特点计算机科学与技术学院张淼264 1基 本 概 念对 象(object)类(class)消 息(message)计算机科学与技术学院张淼265 1 基 本 概 念对 象属性表针 旋钮 其他机械机构行为调节旋钮计算机科学与技术学院张淼266 1 基 本 概 念类类是一个抽象的概念,用来描述某一类对象所共有的、 本质的属性和行为。类类的一个具体实现,称为实例描述这类对象共有的、本质的属性和行为对象具体到一只圆形的或方形的手表手表手表共有的属性(表针、旋钮、内部结构) 和行为(调节旋钮)一块手表计算机科学与技术学院张淼267 1基 本 概 念消 息我们把对象之间产生相互作用所传递的信息称做消息。 发送消息 启 动 接收并响应消息计算机科学与技术学院张淼268 1 基 本 概 念消 息我们把对象之间产生相互作用所传递的信息称做消息。 发送消息 转 向 接收并响应消息计算机科学与技术学院张淼269 2“面向对象”程序设计的特点(1)封装性 (2) 继承与派生性(3) 多态性计算机科学与技术学院张淼270 2 “面向对象”程序设计的特点封装性对象是一个封装体,在其中封装了该 对象的属性和操作。通过限制对属性和操 作的访问权限,可以将属性“隐藏”在对 象内部,对外提供一定的接口,在对象之 外只能通过接口对对象进行操作。 C++通过建立数据类型――类来支持 封装和数据隐藏。封装性增加了对象的 独立性,从而保证了数据的可靠性。一 个定义完好的类可以作为独立模块使用。计算机科学与技术学院 张淼内 动机 作械 零 件外读调 表节 盘旋 钮271 2 “面向对

我要回帖

更多关于 vc2013 x86 的文章

 

随机推荐