C高级编程课程讲义.ppt

上传人:max****ui 文档编号:6335569 上传时间:2020-02-23 格式:PPT 页数:88 大小:1.61MB
返回 下载 相关 举报
C高级编程课程讲义.ppt_第1页
第1页 / 共88页
C高级编程课程讲义.ppt_第2页
第2页 / 共88页
C高级编程课程讲义.ppt_第3页
第3页 / 共88页
点击查看更多>>
资源描述
C 高级编程 Overview Module1 面向过程的C Module2 面向对象的C Module3 C 设计模式 Module1 面向过程的C 从C到C 内存管理数组字符集和字符串指针和引用函数其它 从C到C 语法增强新的运算符变量声明更加灵活函数重载引用类型安全性面向对象封装继承多态 内存管理 在stack上分配内存简单数据类型不使用new创建对象实例函数调用完成自动销毁线程堆栈的限制在Heap上分配内存malloc还是new 检测内存泄漏防止 野指针 回收内存后指针会自动为NULL吗 Demo 动态扩充的字符串缓冲区 数组 1 声明及初始化 inta 1 2 3 intb 3 1 2 3 intc 5 1 2 3 c 3 和c 4 的值默认为0 inta1 2 3 1 2 3 4 5 6 inta2 2 3 1 初始化 第一行为1 0 0 第二行为0 0 0inta3 3 1 2 3 inta4 2 1 2 3 4 5 6 错误 必须声明第二维的数目inta5 3 1 2 3 4 5 6 正确 数组 2 数组的内存形式 数组在内存中的存放全局数组在静态存储区域中存放局部数组 一般在堆栈上存放在堆上动态分配内存线程堆栈的限制 doublearr 500 300 double p newdouble 10 intn 10 double p newdouble n n不必是常量double p newdouble 400 300 错误double p newdouble 400 300 错误 数组 3 指针表现形式 一维数组指针表示二维数组指针表示行地址和列地址 constintARRAY SIZE 5 inta ARRAY SIZE 1 2 3 4 5 int p a 考察 1 a i p i a i a i p i 的含义 2 p 偏移几个字节 a 呢 inta 3 1 2 3 4 5 6 考察 a a i a i a i j a i j a i j 的含义 数组 4 二维数组的指针表示 使用一级指针访问二维数组使用指向一维数组的指针来访问二维数组 inta 3 1 2 3 4 5 6 int p a 0 将二维数组展开成一维数组的方式访问int p a 错误 考察 p i p i p i的含义 int p 3 a 也可写成 int p 3 a int p 3 a 错误 Int p 3 考察 p p i p i p i p i j p i j 的含义 数组 5 动态创建复杂数组 二维数组交错数组 intm 2 intn 3 int p 3 newint 2 3 delete p int p m p数组包含两个元素 每个元素都是int 类型p 1 newint 3 通过p i 来操作每个数组deletep 1 不能使用deletep或者delete p 字符集和字符串 1 字符编码 ANSI UNICODE和UTF 8MultiByte和WideCharwchar t L 前缀 wcslen wcscpy wcslen字符集的转换mbstowcs s和wcstombs sMultiByteToWideChar WideCharToMultiByte wchar tp1 L abcd 考察 wcslen p1 和sizeof p1 的结果 wchar tp1 L abcd charp2 10 intlen wcstombs p2 p1 sizeof p1 len 4 0 字符不计入拷贝字符数目wchar t p3 wchar t malloc 100 mbstowcs p3 p2 100 字符集和字符串 2 兼容字符集 Windows平台与字符集VisualC 编译器字符集设置选项 UNICODE MBCS兼容字符集TCHAR tcslen T TCHARt T aaa 如果编译器定义了 UNICODE sizeof t 8 如果定义了 MBCS sizeof t 4 字符集和字符串 3 声明字符串 使用指针使用数组 char p1 abcd char p2 abcd 考察 内存中有几个 abcd 存在 p1 p2是否成立 charp1 10 a b c d 0 注意结尾的 0 charp2 abcd 自动添加 0 结尾charp3 abcd charp4 a b c d 仅仅声明一个字符数组而非字符串考察 1 sizeof p strlen p 的值分别是多少 2 p2 p3 字符集和字符串 4 字符串操作函数 修改单个字符字符串长度模拟编写strcpy方法为何采用const作为参数为何返回char 0 会被拷贝吗 Demo charp1 10 abcd char p2 abcd p2指向常量字符串p1 0 x OKp2 0 x 错误 常量字符串不可修改 charp1 a t nc 考察 strlen p1 和sizeof p1 指针与引用 1 概念 指针与指针变量引用的定义引用必须在声明时立即初始化 不允许空引用引用一旦初始化 就不能再引用其它数据引用和被引用的变量实际上代表同一个内存的数据 doublea 10 double p 考察 1 p是指针变量 则sizeof p 2 p含义是什么 inta 100 int考察 1 a与 b的关系 2 a 指针与引用 2 混合使用 指针指向某个引用引用一个地址 doublea 100 double考察 1 a p和 b的关系 2 修改a b或 p的值 另两个是否联动 doublea 100 double p和rp是完全相同的 且都是变量a的地址考察 sizeof b sizeof rp 指针与引用 3 作为参数传递 按值传递按地址传递按引用传递 voidIncrease int 指针与引用 4 指针与常量 指向常量的指针指针常量 inta 100 intb 200 constint pci 是否成立 inta 100 intb 200 int constpci 错误考察 如果有constint constpci a 则情况如何 指针与引用 4 引用与常量 将一个引用设置为常量后 不能通过该引用修改数据 但仍可通过被引用的变量来改变 被引用的数据是常量 引用本身也必须是常量 inta 100 constint OK constinta 100 constint 错误 指针与引用 5 Practice chars1 abcdefg chars2 1234567 char p1 s1 constchar p2 s1 char constp3 s1 constchar constp4 s1 考察 下列哪些语句有效 p1 0 k p2 0 k p3 0 k p1 s2 p2 s2 p3 s2 p4 s2 函数 1 Extern C语言中的Extern和StaticC 中的extern C 允许在C 中调用C编写的函数允许在C中调用C 编写的函数Demo 如何在C 和C之间实现互操作 cfile h文件 externintadd intx inty cfile c文件 intadd intx inty returnx y cpp cpp extern C include cfile h 其它格式 extern C intadd intx inty extern C intadd intx inty intsub inta 函数 2 函数指针 声明原型指针赋值函数调用函数指针作为参数传递 int fun intx inty 或者int fun int int 设存在函数intmax inti intj int fun int int max 或者fun max fun 10 20 voidprocess intx inty int f int int process 10 20 max 函数 3 函数指针 设有函数定义 intmyequal1 char s1 char s2 类型定义 typedefint equal char char 则可以声明 equaleq myequal1 并且调用 eq s1 s2 函数 4 缺省参数 注意缺省参数必须出现在所有非缺省参数的后面防止函数重载时的二义性 voidf inti intj 10 intk 20 调用 f 1 20 相当于 f 1 20 20 而 f 1 相当于 f 1 10 20 函数 5 参数个数不定 回顾printf s 编写自定义得可变参数个数函数 stdarg h intaverage intfirst intcount 0 sum 0 i first va listmarker va start marker first while i 1 为方便起见 假定参数以 1结尾 实际工作中应通过某种方式确定参数的个数sum i 例如printf就是通过格式化串中的 确定的count i va arg marker int va end marker return sum sum count 0 其它 sizeof针对字符串的sizeof针对数组和指针的sizeof针对结构体的sizeof变量赋值a b c 3 int x y int x yconst和define作用域限定运算符无名共用体枚举 Module2 面向对象的C 构造和销毁参数和返回值const修饰符运算符重载虚函数友元模板其它 构造和销毁 1 数据声明和初始化 classA public A d2 10 d2 10error staticintd1 staticintd1 100 error constintd2 constintd2 10 error staticconstintd3 200 intA d1 100 constintd3 200 构造和销毁 2 初始化列表 classBclassC publicB public public B i 0 C j 0 B inti i i C inti intj B i j j inti intj 成员变量较少的情况下尽量使用初始化列表各变量在初始化列表中出现的顺序最好与变量声明的顺序一致 构造与析构 3 拷贝构造函数 函数原型调用场合默认拷贝构造函数成员变量之间的 值 拷贝 A constA other Aa1 10 构造函数Aa2 a1 拷贝构造函数Aa3 a1 拷贝构造函数 构造与析构 4 拷贝构造函数 编写拷贝构造函数的必要性 ClassA private char name public A constchar data name newchar strlen data 1 strcpy name data A constA如果未定义拷贝构造函数 会有何种后果 构造与析构 5 赋值函数 赋值函数原型调用场合编写赋值函数的必要性 A operator constA other Aa1 10 为a1调用构造函数Aa2 为a2调用默认构造函数a2 a1 为a2调用赋值函数 区别Aa2 a1 A 有何局限 构造与销毁 5 初始化列表与拷贝构造函数 子对象在构造函数列表中初始化直接调用拷贝构造函数子对象在构造函数中赋值先调用子对象的默认构造函数调用赋值函数为子对象重新赋值 classA Bb public A Bb1 b b1 先调用默认构造函数 再调用赋值函数 A Bb1 b b1 调用拷贝构造函数 构造和销毁 6 构造和析构顺序 调用基类构造函数为各子对象调用构造函数如果有多个子对象 则各个子对象构造顺序与声明顺序一致 而不依赖初始化列表中出现的顺序本类构造函数析构函数的顺序与构造函数相反如果没有显式调用基类或子对象构造函数 那么将调用其默认构造函数 如果默认构造函数不可访问 则编译错误 构造与销毁 7 内存回收 析构函数作用何时调用通过指针使用对象new deleteNULL指针与野指针Demo构造函数 拷贝构造函数 赋值函数 析构函数综合使用实例分析 参数和返回值 1 传递数组 voidf char arr arr 0 A 修改可以成功voidf char arr arr newchar 10 修改无效strcpy arr 12345 voidf char arr arr newchar 10 修改可以成功strcpy arr 12345 参数和返回值 2 传递对象实例 实参对象拷贝给形参对象实参与形参不是同一个对象 classA public intage voidf Aobj obj调用拷贝构造函数将实参a拷贝给自己 obj age 10 实际修改的是obj对象的值 而非实参a对象 voidmain Aa a age 20 f obj a age仍然是20 参数和返回值 3 传递对象引用或指针 省去了参数对象之间的拷贝 提高效率 voidf A 修改obj就是修改a voidf A pobj pobj指向a所在的地址 pobj age 10 通过指针修改a 参数和返回值 4 返回对象实例 ACreateA Aobj 在堆栈创建局部对象obj age 10 returnobj obj被拷贝给一个临时对象tmp 函数结束 堆栈弹出 局部对象obj被销毁调用 Aa 调用A的默认构造函数a CreateA 调用a的赋值函数将tmp对象赋给aAb CreateA 情况会有所不同 obj直接通过拷贝构造函数拷贝给b 理解隐含的构造函数 拷贝构造函数 赋值函数调用 参数和返回值 5 返回对象指针 返回无效的对象指针 A CreateA Aobj obj age 10 return 没有临时对象产生 没有拷贝构造函数和赋值函数调用考察 既然p得到的地址没有意义 为什么有些情况下通过p来访问对象的数据 仍然可以成功呢 参数和返回值 6 返回对象指针 返回有效的对象指针 A CreateA A pObj newA pObj age 10 returnpObj 由于pObj分配再堆而不是堆栈上 因此不会被自动销毁调用 A p NULL 这不会引起调用A的默认构造函数p CreateA deletep 释放内存 参数和返回值 7 返回对象引用 返回对象引用可以避免临时对象的产生但是要特别注意 不要返回无效的引用 A b引用obj 但obj已经销毁 因此b无效考察 为什么赋值函数中可以并且应该返回引用 参数和返回值 8 编写高效的return 直接在return语句中构造对象将有助于减少临时对象的创建和销毁 AGetA Aa 10 创建临时对象 returna 调用拷贝构造函数将临时对象赋给obj 然后销毁临时对象returnA 10 直接把临时对象创建在obj的内存单元中 Aobj GetA const修饰符 1 修饰参数和返回值 修饰参数编译器确保该参数在函数内不会被修改修饰返回值返回结果是常量 不能修改 考察 f inti 与f constinti 有何区别 constcomplexoperator constcomplex 考察 1 c1和c2声明为常量引用有什么好处 2 设obj1 obj2 obj3都是complex 则 obj3 obj2 obj1是否合法 3 函数为什么不返回一个引用 const修饰符 2 常函数 对于一个不会修改数据成员的类成员函数 建议声明为常函数常量实例只能调用函数的const版本非常量实例一般调用函数的非const版本如果一个函数只有const版本而没有非const版本 那么非常量实例可以调用const版本Const函数内部不能再调用非const函数 intGetModule returnreal real image image intGetModule const returnreal real image image 如果 complexc1 1 2 c1 GetModule 则调用非constconstcomplexc2 1 2 c2 GetModule 则调用const 运算符重载 1 实现方式 重载为类实例成员函数重载为友元函数考察 重载了 后 还需要重载 吗 Complex friendComplexoperator Complex 运算符重载 2 操作符 classCount public intnum Count num 0 Count 重载运算符 3 编写类型转换函数 Complexoperator doubled 允许double隐式转换成Complex this real 0 0 this image 0 0 operatordouble returnreal 允许Complex隐式转换成double调用 Complexc c 2 0 doubled c 考察 1 能否写成 Complexc 2 0 如何允许这种写法 2 区别隐式转换与赋值函数 运算符重载Demo 复数类 虚函数 1 多态 classShape public voidDraw 基类classRectangle publicShapeclassEllipse publicShape public voidDraw public voidDraw 不应用多态 考察 如果有N个子类 voidDraw Rectangle pRec pRec Draw voidDraw Ellipse pEll pEll Draw 应用多态 voidDraw Shape pShp pShp Draw 虚函数 2 virtual关键字 如果基类函数没有virtual关键字 静态联编动态联编子类函数还需要编写virtual吗 为什么析构函数要写成virtual 纯虚函数和抽象类 虚函数 3 区分重载 重写 隐藏 Overload同一个类中同名但不同参数的函数Override子类重新实现基类继承的函数子类函数与基类函数原型完全一致Hide子类与基类定义了同名函数但原型不同 则子类隐藏基类的函数Demo 隐藏示例 虚函数 4 多重继承 为什么需要多重继承如何避免多重继承重的二义性虚继承MFC中多重继承的例子 友元 1 友元函数 友元函数可以做什么 友元函数可以是全局函数也可以是类成员函数不要使用访问限定符来修饰friend语句 friendintglobal func friendintsomeclass class func class func本身可有访问限定符 友元 2 友元类 类A是类B的友元类 则类A中所有函数都可以访问类B中的任何成员声明友元类Demo 一个链表维护类 friendclasssomeclass 模板 1 模板的必要性 voidswap int i int j voidswap float i float j voidswap uint i uint j 不使用模板 使用模板 templatevoidswap Tswap a b 模板 2 模板函数 单类型模板多类型模板模板函数代码在哪里编写 templatevoidSwap T1 a T2 b 模板 3 模板类 类声明类中相关变量 参数和返回值类型用T代替函数实现可以在类声明内或外部实现 h文件还是 cpp文件 使用 templateclassStack voidpush Ta templatevoidStack push Ta Stacks 模板 4 模板应用实例 C 标准模板库ATL活动模板库 其它 1 局部类和嵌套类 局部类在一个函数的内部定义所有函数体都在类声明内 不能有静态变量可访问函数中已经声明的局部变量不可直接访问函数所在类的成员嵌套类在包容类的内部定义嵌套类中可直接访问包容类的任何成员包容类可以访问嵌套类的共有成员 不能访问非公成员从包容类外部访问嵌套类成员时 访问限定取最严格集Demo MFC使用嵌套类实现COM多接口 其它 2 内联函数和宏 宏定义的不足编译器简单替换 不进行类型检查容易造成歧义内联函数函数体直接写在类声明内也可用inline关键字在类声明外编写 建议 definemax a b a b a b 考察 i 5 j 0 计算max i j inlineintmax inta intb returna b a b 其它 3 强制类型转换 static cast可用于简单数据类型之间以及对象指针的转换运行时不进行类型检查 因此不能保证转换的安全性 即使转换失败 也会返回某个地址程序员应确保转换确实可行dynamic cast不能用于简单数据类型之间的转换运行时如果转换失败 则返回NULL ch static cast i inttocharB pb newD D pd dynamic cast pb ok pbactuallypointstoaD 其它 4 异常处理 try char buf newchar 512 if buf 0 throw Memoryallocationfailure catch char str cout Exceptionraised str n 抛出和处理简单异常 throwCMyException catch CMyexceptionex 抛出自定义异常类 处理多个异常 try catch char str catch intcode catch 其它 5 对象数组对象数组的初始化问题Demo面向对象的C 实现 Stack类面向对象的二叉树实现使用多态性构造的有限状态自动机 C 设计模式 核心设计模式创建型结构型行为型为什么要使用设计模式合理使用设计模式 创建型模式 1 简单工厂 由一个工厂类决定创建那些类的实例该工厂类可以创建多个类别的对象 创建型模式 2 工厂方法 工厂定义创建产品对象的接口 实际的创建工作在工厂子类中完成每个子类一般专门负责创建一种产品 因此该子类只需要了解它所需要创建的产品类型即可COM的类工厂 创建型模式 3 抽象工厂 抽象工厂为创造一系列产品提供一个抽象接口 由子类实现具体对象的创建每个工厂一般负责创建一系列 多种 产品 创建型模式 4 生成器模式 将对象的创建步骤和创建细节分开构造器负责产品各个部分构造导航器负责组装产品 创建型模式 5 原型模式 对象通过赋值自己创建新的实例区分浅复制和深复制 创建型模式 6 单件模式 确保某个类只有一个实例由类自行实例化并提供获得实例的接口 结构型模式 1 适配器模式 使接口不同的两个对象能协同工作客户需要使用目标接口 目标类 现有接口 待配类 与目标接口不一致适配器即兼容目标 也兼容待配类类适配器同时继承Target和Adaptee对象适配器仅继承Target内部使用Adaptee对象 结构型模式 2 组合模式 体现 部分 整体 关系 结构型模式 3 装饰器模式 为对象提供功能扩展 同时保持对象的透明性 结构型模式 4 代理模式 通过代理对象访问实际对象 从而实现对象的受控访问COM跨进程调用Web服务代理 结构型模式 5 享元模式 支持大量的细粒度对象 通过享元工厂控制各个享元对象的创建和访问COM 对象池 结构型模式 6 外观模式 为具有多个接口的子系统提供一个统一的接口 以简化客户对该子系统的调用 结构型模式 7 桥接模式 分离抽象与实现 从而使得它们可以独立变化 行为型模式 1 职责链 将多个对象连成一条链 并沿着链传递客户请求 直到有一个对象处理它为止多个异常的处理方式 行为型模式 2 命令模式 将一个请求封装为一个对象 使请求与接受请求的对象分离还可对请求进行排队或记录请求日志 并支持可撤销的操作 行为型模式 3 解释器 给定一个语句 定义其语法形式 再定义一个解释器 根据语法形式将该语句以面向对象的方式表达出来 人机交互 用表达式表示的逻辑和数学运算 行为型模式 4 迭代器 提供一种方法顺序访问一个聚合对象种的各个元素 且不暴露该对象的内部表示for foreach 行为型模式 5 备忘录模式 在不破坏封装性的前提下 捕获一个对象的内部状态 在该对象之外保存这个状态 以便以后可以恢复到原先保存的状态 行为型模式 6 状态模式 使对象在不同的状态下改变其行为对象在不同的上下文中 相同的动作导致的结果不同 行为型模式 7 观察者模式 定义对象间一对多的依赖关系 当一个对象发生变化使 所有以来它的对象都得到通知并自动更新MFC中的文档 视结构 行为型模式 8 中介者模式 用一个中介对象将一系列对象交互封装 从而降低这些对象间的耦合性并可以独立的改变对象间的交互关系用户界面上多个控件之间的交互 行为型模式 9 策略模式 将算法封装 使系统可以更换或扩展算法 所有子类的目标一致 但实现的方法不同 加密算法使用函数指针的策略模式 行为型模式 10 模板方法模式 定义一个操作中的算法的骨架 将实现延迟到子类中模板方法是代码复用的基本技术关于虚函数 行为型模式 11 访问者模式 实现通过统一的接口访问不同类型元素的操作 并且通过这个接口可以增加新的操作而不改变各元素的类 关于友元
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!