C语言试题学习考试大全.ppt_第1页
C语言试题学习考试大全.ppt_第2页
C语言试题学习考试大全.ppt_第3页
C语言试题学习考试大全.ppt_第4页
C语言试题学习考试大全.ppt_第5页
已阅读5页,还剩166页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 面向对象程序设计 教材 C 程序设计实践教程光盘 学习指导 习题祥解 模拟试卷出版 华中科技大学出版社编著 马光志讲授 华中科技大学计算机学院马光志maguangzhi 2 第1章引论 3 1 1程序设计语言 机器语言 计算机自身可以识别的语言汇编语言 接近于机器语言的符号语言高级语言 接近自然语言的程序设计语言 如ADA C PASCAL FORTRAN BASIC面向对象的语言 描述对象 特征 及 行为 的程序设计语言 如C SMALLTALK等面向对象基于组件的语言 面向对象且类型能成为组件的程序设计语言 如Java C 等 4 1 2程序编译技术 编译过程 预处理 词法分析 语法分析 代码生成 模块连接 预处理 通过 define宏替换和 include插入文件内容生成纯的不包含 define和 include等的C或C 程序 词法分析 产生一个程序的单词序列 一个单词或词法单位可以是保留字如if和for 标识符如sin 运算符如 常量如5和 abcd 等 语法分析 检查程序语法结构 例如if后面是否出现else 代码生成 生成低级语言代码如机器语言或汇编语言 C和C 语言的标识符编译为低级语言标识符时会换名 C和C 的换名策略不一样 模块连接 形成一个可执行的程序 静态连接是编译时由编译程序完成的连接 动态连接是运行时由操作系统完成的连接 关于BC与VC BC完全支持国际标准 VC支持70 左右 编译器推荐C builder6 0 否则本书的例子有很多不能运行 5 预处理的例子 假如stdio h的文件内容如下 externintscanf constchar externintprintf constchar 程序test c的文件内容如下 include definepi3 14voidmain printf area lf pi 5 5 预处理的结果 由test c文件得到如下内容 externintscanf constchar externintprintf constchar voidmain printf area lf 3 14 5 5 6 1 3面向对象的语言及程序设计 纯OO型语言 程序全部由类构成 SMALLTALK JAVA C OBJECT ORIENTEDPASCAL 混合型OO语言 程序由类 过程或函数以及变量定义构成 C VB NET 面向对象程序设计经历系统分析 系统设计 对象设计和对象实现四个阶段 系统分析最初建立对象模型 动态模型及功能模型 供其他阶段细化 其中对象模型最为重要 描述对象 类型之间的关系 面向对象的分析与设计各阶段共用上述三个模型 阶段之间的界限不是十分明显 能更好地支持软件工程的快速原型法 7 1 4面向对象的基本概念 函数绑定 函数调用和函数入口关联的过程 早期绑定 发生在程序开始执行以前 由编译程序静态连接 或者由操作系统动态连接完成 将函数入口地址填写到函数调用处 晚期绑定 发生在程序执行过程中间 由程序自己完成 对象 现实世界具体的或抽象的 事物 经历产生 活动 死亡等阶段 体育比赛的 运动员 和 赛局 分别为具体和抽象的对象 类 描述对象特征和行为的类型 有结构的类属于复杂类型 简单类型和复杂类型变量 对象 初始化 产生 形式趋向统一 对象既可以是变量 也可以是常量 就象简单类型既有变量也有常量一样 统一起来 对象分为简单类型对象和复杂类型对象 8 封装 将对象的 特征 和 行为 包装在一起 形成对象的类型定义 分别描述对象的 组织结构 和 功能 封装定义了对象的边界 提供了外部访问的接口 屏蔽了对象的 行为 细节 交互 直接交互指一对象调用另一对象的 操作 功能 或 函数 间接交互通过发送或监听消息完成 C 程序的对象既可以直接交互 也可以通过操作系统提供的消息机制间接交互 面向对象基于组件的语言可通过自己的事件 消息机制间接交互 9 重载 一个函数名称用来定义完成不同功能的多个函数 参数个数和类型随完成功能的不同而不同 将运算符看作函数 操作数就是 参数 5和8 3分别是有一个和两个参数的减法函数 可记为operator int operator int int 多态 通过一个函数名调用函数表现出的不同行为 早期绑定的多态是静态多态 晚期绑定的多态是动态多态 重载函数表现的行为是静态多态 虚函数表现的行为是动态多态 由此可见 重载函数使用早期绑定 虚函数使用晚期绑定 多态 一般指动态多态 C 已经自嵌入地重载了简单类型运算函数 故不允许对简单类型进行运算符重载 换言之 运算符重载函数的参数不能都为简单类型 必须至少有一个参数代表对象 例如 5 8 3调用的是自嵌入的减法运算重载函数 函数名见上 重载函数要么参数个数不同 要么参数类型不同 10 继承 一个对象获得另一个或多个对象的 特征 和 行为 从而实现了软件重用 例如 小孩长相象父母是获得父母 特征 走路象父亲是获得父亲 行为 继承有取代继承 包含继承 受限继承和异化继承等方式 抽象 一种抽象形式是从对象 事物 到类型 概念 另一种形式是从低级类型 概念 到高级类型 概念 从事物 张三 李四 抽象出 学生 的概念 从 学生 教师 的概念可抽象出 师生 的概念 抽象类 抽象级别最高的类 无法描述具体特征和行为 例如 从 点 线 圆 抽象出 图形 的概念 无法说出 图形 有何特征 也无法说明其绘图行为 11 1 5C 语言的特点 C的超集 完全兼容C 代码质量高 速度快 多继承的强类型的混合型的OO语言 支持面向对象的运算符重载 至少一个操作数的类型代表对象的类型 提供函数模板和类模板等高级抽象机制 支持面向对象的异常处理 支持名字空间namespace 12 1 6 的程序结构 支持C的注解 和C 新注解 到本行结束 强类型要求变量和函数先声明再使用 printf等标准函数必须先 include再使用 扩展名为 h的文件只应包含变量 函数的说明 其定义应出现在扩展名为 cpp的程序文件里 变量说明 externintx 说明只含类型和名称变量定义 intx y 3 externintz 4 定义包括初值函数说明 无函数体的原型声明 可无参数名 例如 doublesin double C 须说明extern C longsum int 以调用C的sum 编译成低级语言后 C 和C的sum的低级语言名称相同 类iostream对象cin通过函数 输入 cout通过 输出 13 继续支持stdio h 强类型要求必须先 include再使用 其中包含了变量和函数说明 intscanf constchar 返回成功输入变量的个数 intprintf constchar 返回成功输出字符的个数 intx printf 9876543210 结果x 10 输出10个字符 inty printf d 98765 y 5正好是十进制有效位数 流iostream类对象 变量 cin通过重载 运算符函数完成输入 就象 运算符一样 可以自左至右连续运算 试比较变量cin x y z的运算 x y z x y的和 一个值 再和z进行 运算 cin y z cin y的结果 为cin 再和z进行 运算 等于cin y cin zcin关于 运算的结果为cin cout关于 和 运算 14 第2章C 类型 变量及函数 15 2 1声明及定义 常量表达式 值能被编译程序计算且结果为常量的表达式 单个或多个常量构成的常量表达式如下 3 单个常量构成的常量表达式3 14 3 3 r 3的圆面积 含义明确且不降低效率sizeof2 sizeof int 2 sizeof非函数 如是 以下 表达式应调用printfsizeof 3 printf ABC sizeof int 未调printf 不打印ABC任意表达式 由常量 变量 函数调用等构成的表达式 不能被编译程序计算 只能在程序运行时计算 类型表达式 int 2 是类型表达式 非数值表达式 16 左值表达式 在等号左边出现的值表达式 如下红色标注 非const类型的变量 intx x 2 引用非const类型的变量 intx为右值 因为不能有赋值语句x 8 C语言的函数调用为右值 因C的函数调用只在等号右边出现 但C 返回左值的函数可以出现在等号左边 见上int f 一个表达式既然能出现在等号左边 就必然能出现在等号右边 故左值表达式是右值表达式 反之则不一定成立 例如 常量8是右值表达式 它不能出现在赋值号 的左边 17 变量定义须有初值 函数定义须有函数体 否则只能称为说明或声明 C语言声明和定义 变量声明和定义必须在语句之前 一般只允许以常量表达式初始化变量 只有函数内定义的非static变量可用任意表达式初始化 C 语言声明和定义 变量声明和定义不必在语句之前 所有变量都可以用任意表达式初始化 函数内定义的非static变量如不初试化 其值不确定 新编译器允许在if while和for的条件部分定义变量 仅限于其语句部分可以访问 由开工函数产生 初始化全局变量 由收工函数消灭全局变量 18 includeexterninth 0 C变量定义方式 常量表达式初始化externinti 变量声明 C和C 都可先声明后定义inti C定义方式 初始化i 0intj i printf ABC C 方式 任意表达式 输出ABCstaticintp j sizeofprintf ABC C 方式 不输出ABCvoidmain void staticintn j 5 C 定义方式 任意表达式初始化intk i 20 C定义方式 k值随机for intj k 2 j 9 j intm 5 C定义方式 intq 23 C 定义方式 定义出现在for语句后struct intk m b j 3 5 C 定义方式inta 4 scanf d C 定义方式 即使main函数体为空也会输出ABC 程序作为对象 产生 活动和灭亡 19 2 2类型定义 解释原则 定义中出现的运算符 优先级高的先解释 相同时按结合性解释 自左至右 或反之如 y 1 5 y 5 5 注意f左边是 右边是 优先级高 y x f f 5 5 f 10 9 19 20 void用于表示函数无参或者无返回值 void p所指向的实体单元字节数不定 因此 p可以指向任何实体 即可以将任何指针和任意类型变量的地址赋给p 或者调用时通过值参传递给参数p 如果p是函数参数 对指向的实体单元赋值时 类型或字节数必须确定 所以必须进行强制类型转换 double p 3 2 const的变量 参数和函数返回值不能被 本 程序修改 因此 定义变量时必须同时初始化 以后不能修改其值 即const变量和参数是右值 参数的初始值在调用函数时传递 此后不能在函数体内修改参数值 21 constdoublepi 3 141592654 只读变量pi必须同时初始化intoutput constchar f 函数内不能有 f A return1 voidmain void char fmt Area lf n output fmt pi 5 5 fmt指向的格式字符串未变 故output fmt pi 6 6 可继续用fmt指向的格式字符串 值参传递是将fmt的值传给output的函数参数f f在output的函数体内相当于一个局部指针变量 f值可以在output函数体内被修改 传递后f已和fmt指针无关 fmt指针的内容保持不变 f指向的字符constchar不能被修改 并不意味指针f本身不能被修改 若要求f也不能在output函数体内被修改 则应这样定义constchar constf参数 由于值参传递后f与fmt无关 既无论如何fmt指针变量的值不变 定义constf对参数f意义不大 且f不能被修改可能需要output定义更多的可变变量 22 指向const实体的指针可以用指向非const实体的普通指针或地址赋值 但反之是错误的 intx 4 p 正确 s 2 p 1和e相等 23 volatile声明定义挥发变量 参数和函数返回值 即使 本 程序未作修改 存于内存的值也可能发生变化 这意味着其他程序或进程在改变volatile变量的值 这类变量可做信号灯使用 通常用于两个程序或进程同步 const表示 本 程序不能修改 volatile表示 本 程序没修改但值会发生变化 两者都未排除其他程序或进程修改 故两者同时说明变量和参数是不矛盾的 volatileintx 3 x的值可以以后再初试化if x 4 cout xchangedbyotherroutines constvolatileinty 4 y是const 必须同时初始化y 7 错误 y是const 不能修改y的值 但y的值可能变化if y 8 cout ychangedbyotherroutines 24 2 3引用类型 运算符 可以声明和定义引用类型的变量 参数和返回值 被引用的值可能是const volatile和普通的可修改的变量 引用是被引用变量的别名 逻辑上不被看作独立存在的实体 即逻辑上不为引用变量分配内存 因此 定义引用变量的同时必须同时初始化 以使引用变量关联和 共享 被引用变量的内存 如果引用const类型变量 则可以用右值表达式初始化引用变量 该引用变量本身也是const的 即右值 注意左值即右值 故可用左值表达式初始化引用变量 如果引用非const类型变量 则必须用类型相同的左值表达式初始化 该引用变量本身也是非const的 即左值 否则 将产生同类型的临时变量作为左值供引用变量引用 例2 12 引用物理上被编译成低级语言的指针 例2 10 引用参数占用较少的栈 指针一般只有几个字节 故引用参数传递实参的效率更高 25 inti 1 constint f y 返回y引用的i 故 f y 1 相当于i 1 f y 1 为左值由i代表 f y 1 2相当于i 2 故x y z i 2 26 主调函数引用被调函数基于栈的自动变量 被调函数的参数和局部变量 将导致程序结果不确定 例2 15 引用变量是被引用实体的别名 逻辑上不分配内存 访问引用变量即是访问被引用的实体 数组元素不能为引用 否则数组元素不分配内存 若元素不分配内存 则数组空间不存在 指针不能指向引用变量 被引用的实体必须是分配了内存的实体 寄存器变量可被引用 可被编译为分配内存的自动变量 位段成员不能被引用 计算机没有按位编址 而是按字节编址 引用物理上编译为指针 存放被引用实体内存地址 引用变量不能被引用 对于intx int并非表示z引用y 引用变量 z y为同类型变量赋值 表示z引用y所引用的变量i 引用引用变量的定义如int w 27 structA intj 4 j为位段成员intk a intj 0 正确 a k不是位段 28 2 4函数参数 函数原型 用于描述函数的名称 参数和返回类型 参数只需说明参数类型 参数名称可以不说明 调用时根据函数原型 检查实参和形参是否类型相容 doublesin doublex 有参数名的原型声明doublecos double 无参数名的原型声明重载函数 老版本C 用overload声明重载 新版通过参数差异识别重载函数 即若参数的个数或者类型有所不同 则同名的函数被视为重载函数 重载只与参数有关 与返回类型无关 若参数个数和类型完全相同 仅仅返回类型不同是不容许的 29 include includeoverloadGetTime 本行可以省略longGetTime void return1 longGetTime int 30 省略参数 用省略号 表示 省略号出现的地方可以有任意个任意类型的参数 例如常用的printf函数 intprintf constchar format 编写n个整数求和的省略参数的函数 longsum intn longs 0 int p 执行完后s 9 问题 如何实现wprintf WND constchar 31 缺省参数 函数声明或定义时参数有缺省值 调用时若没有传入实参 就取参数的缺省值传给形参 可用任意类型的表达式指定参数的缺省值 但表达式中不能出现同一参数表的参数 否则 由于参数的计算顺序问题 自左至右或自右至左 对不同编译环境会带来可移植性问题 intf intx inty x 错误 表达式x 有同一个 参数表的参数x对于x 3 f x 表示使用y的缺省值调用 等价f x x 自左至右计算参数等价于f 3 3 自右至左计算参数等价于f 4 3 故对不同的编译器来说是不可移植的 所有缺省参数必须出现在非缺省参数的右部 不能同时在声明和定义中定义缺省参数的 即使表达式相同 值 即使两个表达式看起来完全一样 intw 3 b intx w 声明正确 指定缺省值x wintu w intb intx w returnx 再定义则错 两w值相等吗 32 调用开销 调用时通过压栈传递实参 调用转移 压栈保护寄存器等的开销 返回时出栈恢复寄存器 返回函数值 实参出栈等的开销 函数体越小 调用开销相对越大 例如调用开销共计10条指令 程序有100个调用 被调函数体5指令 则程序长 100 10 5 1005被调函数体20指令 则程序长 100 10 20 1020函数内联 用保留字inline声明或定义 内联函数后 在调用处直接插入函数体 一般对函数体较小的函数内联 不生成内联函数的代码 即函数在低级语言级不存在 内联函数体太长 大于调用开销 反而会使编译后的程序总长度加长 被调函数体5指令 程序长100 5 500 内联后程序变短被调函数体20指令 程序长100 20 2000 内联后反而变长 33 内联失败 在低级语言级生成函数代码 不在调用处插入函数体 继续使用调用指令调用函数 失败原因 包含产生分支转移的语句 if switch while for dowhile 函数调用 内联函数的定义出现在调用之后 有关于取内联函数地址的指令 程序员要取地址 内联函数同时被定义为虚函数或纯虚函数 编译程序要自动取虚函数的地址 注意 内联失败并不导致程序出错 内联成功使函数的作用域局限于当前程序文件 即相当于在函数前使用了static 34 inlinedoublegirth doubler 函数原型声明 无函数体inlinedoublearea doubler 函数定义 包括函数体return3 1416 r r voidmain void doublem m girth 5 0 内联失败 编译为函数调用指令m area 5 0 内联成功 编译为m 3 1416 5 5 doublegirth doubler return3 1416 2 r 35 第3章C 的类 36 3 1类的声明及定义 类的声明 由保留字class struct或union加上类的名称构成 类的定义 包括类名的声明部分和类由 括起来的主体两部分构成 类的实现 通常指类的函数成员的实现 即定义类的函数成员 class类型名 前向声明class类型名 类的定义private 私有成员声明或定义 protected 保护成员声明或定义 public 公有成员声明或定义 类保留字 class struct或union可用来声明和定义类 37 使用private protected和public保留字标识每一区间的访问权限 同一保留字可以多次出现 同一区间内可以有数据成员 函数成员和类型成员 习惯上按类型成员 数据成员和函数成员分开 成员可以任意顺序出现在类定义中 函数成员的实现既可放在类体外面 也可内嵌在类体定义中 此时会自动成为内联函数 若函数成员在类的定义体外实现 则须在函数返回类型和函数名之间 使用类名和作用域运算符 指明该函数成员所属的类 定义类时不允许初始化数据成员 应由构造函数完成 类的定义体花括号后要有分号作为定义体结束标志 38 include include 如果函数同名 可用单目 访问全局函数structSTRING 定义存放字符串的类 可用struct classtypedefchar CHARPTR 类型成员CHARPTRs 数据成员 等价于char s intstrlen 求串长 普通函数成员 隐含this参数STRING CHARPTR 构造函数无返回类型 有this STRING free s 析构函数无返回类型 有this 自动内联 STRING strlen必须用 限制strlen 否则自递归intSTRING strlen return strlen s STRING STRING char t strcpy s char malloc strlen t 1 t structSTRINGx simple 可省略struct 自动调构造函数voidmain STRINGy complex z 返回前自动调y的析构函数 返回后自动调x的析构函数 39 构造函数和析构函数 是类封装的两个特殊函数成员 都有类型固定 现为STRING constthis 的隐含参数this 没有返回类型 构造函数 函数名和类名相同 除this外 还可在参数表定义其它参数 析构函数 函数名和类名同且带 不能在参数表显式定义任何参数 如果类没有自定义构造函数和析构函数 则C 为类提供缺省的参数表无参的构造函数和析构函数 构造函数用来产生对象 为对象申请资源 初始化数据成员 可在参数表显式定义参数 通过参数变化实现重载 析构函数用来毁灭对象 释放对象申请的资源 析构函数的参数this类型固定 且参数表不能显式定义参数 故无法通过参数变化重载析构函数 40 构造函数在定义变量 对象 或通过new产生对象时被自动调用一次 是唯一不能被手动调用函数成员 析构函数在变量 对象 的生命期结束时被自动调用一次 通过new产生的对象需要用delete手动释放 调用析构 析构函数可被手动反复调用 有些资源是不能反复析构的 例如不能反复关闭文件 因此 必要时要防止对象反复释放资源 全局变量 对象 main执行之前由开工函数调用构造函数 main执行之后由收工函数调用析构函数 局部自动对象 非static变量 在当前函数内定义时自动调用构造函数 在当前函数正常返回时自动调用析构函数 局部静态对象 static变量 定义时自动调用构造函数 main执行之后由收工函数调用析构函数 常量对象 在当前表达式语句定义时自动调用构造函数 语句结束时自动调用析构函数 41 程序不同结束形式对对象的影响 exit退出 局部自动对象不能自动调用析构函数 此类对象申请的资源不能被释放 exit退出后执行收工函数 静态和全局对象资源在exit退出后 由收工函数自动调用析构函数释放 abort退出 所有对象不能自动调用析构函数 局部和全局对象资源都不能释放 abort退出后不执行收工函数 return返回 能够自动调用析构函数 局部和全局对象资源被释放 main通过return返回后会执行收工函数 intmain if error return1 提倡使用return退出 异常处理也会自动调用析构函数 在定义变量 对象 时 最先定义的对象最后自动析构 可随时手动调用析构函数 但要防止反复释放资源 内存资源可以反复释放 因为操作系统提供了容错 42 include include includestructSTRING char s STRING char STRING STRING STRING char t s char malloc strlen t 1 strcpy s t cout Construct s STRING STRING 防止反复释放内存if s 0 return cout Deconstruct s free s s 0 提倡0代替null指针 voidmain void STRINGs1 String1 n STRINGs2 String2 n STRING Constant n cout RETURN n s1 STRING 析构s1 自动析够构s2 s1 43 3 2访问权限 封装机制定义数据成员 函数成员和类型成员的访问权限 提供对外访问接口访问内部私有或保护数据 包括三类 private 私有成员可被本类的函数成员访问 不能被派生类函数成员 其它类的函数成员和普通函数访问 protected 受保护成员可被本类和派生类的函数成员访问 不能被其它类函数成员和普通函数访问 public 公有成员可被任何函数成员和普通函数访问 注意 类的友元不是当前类的成员 可以在private protected和public等任意位置说明 友元可以像类自己的函数成员一样访问类的所有成员 进入class定义的类时 缺省访问权限为private 进入struct和union定义的类时 缺省访问权限为public 44 访问形式 包括取值 赋值 引用 调用 取地址 取内容等 构造函数和析构函数可定义为任何访问权限 访问时要遵守相应权限 构造函数定义为受保护的可在派生类成员函数中产生对象 定义为私有的可在友员函数中产生对象 构造函数只能在定义对象时自动调用 因此不能取构造函数的地址 否则通过函数指针便可手动调用构造函数 析构函数可以自动和手动调用 可以取析构函数的地址 通过函数指针可以手动调用析构函数 45 classGIRL 缺省访问权限为privateintage 私有的 本类函数成员和友员可访问public 访问权限改为publictypedefchar NAME 公有的 都能访问protected 访问权限改为protectedNAMEnickname 本类和派生类函数成员 友员可访问NAMEgetnickname returnnickname 自动内联public 访问权限改为publicNAMEname 公有的 都能访问 w voidmain void main没有定义为类FEMALE的友员GIRL NAMEn w name 任何函数都能访问公有namen w nickname 错误 main不得访问保护成员n w getnickname 错误 main不得调用保护成员intd w age 错误 main不得访问私有age 46 3 3内联及位段 函数成员的内联说明 在类体内定义的任何函数成员都会自动内联 也可使用inline保留字说明函数内联 内联失败 成员函数有分支类语句 定义在使用之后 取函数地址 定义 纯 虚函数 内联函数成员作用域局限于当前程序文件 相当于C的static函数 匿名类的函数成员只能在类体内定义 自动内联 函数中的类只能在类体内定义函数成员 内联 某些编译器不支持在函数中定义类 位段成员 class struct union都可定义成员类型不大于int的位段成员 注意枚举类型被编译为整型 也可以作为位段成员的类型 位段多用于图象和控制 例如 classA inta 3 enum s t c 1 47 classCOMP doubler v public COMP doublerp doublevp r rp v vp 自动内联inlinedoublegetr inline保留字可以省略 后面又定义doublegetv inlinedoubleCOMP getv returnv 定义内联voidmain void COMPc 3 4 doubler c getr 此时getr的函数体未定义 内联失败doublev c getv 函数定义在调用之前 内联成功 inlinedoubleCOMP getr returnr 定义内联 48 对于没有对象的匿名联合 C 兼容C的用法 没有对象的全局匿名联合必须定义为static 局部匿名联合不能定义为static 匿名联合内只能定义公有数据成员 数据成员和联合本身的作用域相同 数据成员共享存储空间 includestaticunion intx y z inty 5 错 本作用域已定义yvoidmain void x 3 cout y 输出3 49 3 4new和delete 内存管理函数和new delete的区别 内存分配 malloc为函数 实参用值表达式 分配后内存初始化为0 new为运算符 操作数用类型表达式 先在底层调用malloc 然后调用构造函数 内存释放 free为函数 实参用指针类型值表达式 直接释放内存 delete为运算符 操作数为指针类型值表达式 先调用析构函数 然后底层调用free 如为简单类型 没有构造 析构函数 指针分配和释放内存 则new和malloc delete和free没有区别 可混合使用 如new分配的内存用free释放 50 new类型表达式 int p newint 等价int p newint 0 数组形式仅第一维下标可为任意表达式 其它维为常量表达式 int q 6 8 newint x 20 6 8 为对象数组分配内存时 必须调用参数表无参构造函数 delete指针指向非数组的单个实体使用deletep 如p指向对象 则先调用析构函数 再释放对象所占的内存 delete 指针指向任意维的数组时使用delete q 否则内存泄露如q指向对象数组 则对所有对象 元素 先调用析构函数 然后释放对象数组占有的内存 若数组元素为简单类型 则可用delete代替 51 new还可对已经析构的变量重新构造 从而减少变量的说明个数 提高内存的使用效率 需高版本C 编译器支持 通常要包含iostream h STRINGx Hello p 这种用法可以节省内存或栈的空间 52 include includeclassARRAY class体的缺省访问权限为privateint a r c public 访问权限改为publicARRAY intx inty int型可用malloc a newint r x c y ARRAY 可用free a 也可用deletea if a delete a a 0 voidmain void ARRAYy 3 5 p main返回前析构yp newARRAY 5 7 不能用malloc ARRAY需要调构造函数deletep 不能用free 否则p未调用析构函数 53 3 5隐含参数this this指针是一个隐含的const指针 不能移动或对该指针赋值 它是普通函数成员的第一个参数 指向要调用该函数成员的对象 this代表当前被指向的对象 当对象调用函数成员时 对象的地址作为函数的第一个实参首先压栈 通过这种方式将对象地址传递给隐含参数this 构造函数和析构函数的this参数类型固定 由于析构函数的参数表必须为空 this参数又无类型变化 故析构函数不能重载 类的静态函数成员没有隐含的this指针 54 classTREE intvalue TREE left right public TREE int TREE constthis TREE TREE constthisconstTREE find int const constTREE constthis TREE TREE intvalue 隐含参数this指向要构造的对象this value value 等价于TREE value valueleft right 0 C 提倡空指针NULL用0表示 constTREE TREE find intv const this指向调用对象if v value returnthis this指向找到的节点if vfind v 0 查左子树returnright 0 right find v 0 查右子树 调用时新this left 55 3 6对象初始化 若存在以下因素 必须自定义构造函数 类若定义了只读和引用类型的非静态 static 数据成员 这些成员必须通过自定义构造函数初始化 若类的基类只定义了参数表有参数的构造函数 这些基类必须通过自定义构造函数初始化 若类A包含类B的非静态对象成员 而类B的构造函数参数表都有参数 则类A必须自定义构造函数 无论参数表是否有参数 以便用实参初试化类B的非静态对象成员 注意 C 缺省的无参的A 只会调用无参的B 初始化位置 在构造函数的参数表之后 函数体之前 所有的基类和数据成员都应在此初始化 并且只能在该处初始化一次 在其函数体内的赋值不应视作初始化 56 数据成员初始化方法 数据成员不能在定义时初始化 必须在构造函数初始化 按照定义的先后次序初始化 与出现在初始化位置列表的次序无关 普通数据成员没有出现在初始化位置时 若所属对象为全局 静态或new的对象 将具有缺省值0 基类和非静态对象成员没有出现在初始化位置时 此时必然调用无参构造函数初始化对其初始化 如果类仅包含公有成员且没有定义构造函数 则可以采用同C兼容的初始化方式 即可使用花括号初始化数据成员 联合类型的对象只须初始化一个成员 共享内存 用new分配的对象数组必须调用无参构造函数初始化 57 structA inta b w 1 2 全部为公有成员 未定义构造函数classB intc public B intx c x 最好是B intx c x classC constintd Be 类B构造函数参数表有参数 类C须定义构造函数public C d 0 e 0 无参构造函数C intx e x d x 重载构造函数按定义顺序d e初始化C intx inty d x e y 只读 引用 对象成员如d e不能在 中赋值 voidmain void 等号右边只能一个值 等于Bm 8 n 9 t 3 Bm 8 n 9 t 2 3 元素C 3 C 5 C 6 C 7 8 C C Cp 6 3 4 5 C 6 C 7 8 C C q newC 3 r newC 4 对象数组为其元素调用C 共4次deleteq delete r 对象数组用delete 析构4次 释放1次对象数组 58 3 7类的存储空间 存储空间 主要同编译有关 也同机器字长有关 如类有基类 虚基类和虚函数 则更复杂 对齐方式 编译时按紧凑和松散方式存数据成员 紧凑方式 数据成员之间没有空白字节 程序占用的内存较少 但跨边界成员的访问时间较长 若成员X的起始地址不能被sizeof X 整除 则称X为跨边界的 松散方式 数据成员之间因边界对齐填补空白字节 程序占用的空间较多 但对齐后不跨边界访问 访问时间较短 Microsoft用紧凑方式 Borland用松散方式 可设编译开关 59 includestructMESSAGE charflag 消息类别标志intsize 消息长度charbuff 255 消息缓冲区longsum 消息累加和 voidmain void cout Sizeofsinglewordis sizeof int 假定sizeof int 2cout Sizeofdoublewordis sizeof long 假定sizeof long 4cout nSizeofMessageis sizeof Message 60 紧凑方式 一个成员紧接着前一个成员存放 则 sizeof MESSAGE 1 2 255 4 262 松散方式 成员不跨边界存放 即成员开始地址必须能被size 成员类型 除尽 对数组则考虑其元素类型 假定MESSAGE的开始地址为0 则 存放flag后填补1字节 使size地址被sizeof int 除尽存放size后不填字节 buff地址能被sizeof char 除尽存放buff后地址用到259 填补1字节使sum地址能被sizeof long 除尽 故sizeof MESSAGE 1 1 2 255 1 4 264 61 第4章作用域及成员指针 62 4 1作用域 作用域 标识符起作用或可被访问的范围 作用域运算符 既是单目运算符 又是双目运算符 的优先级为最高级 结合性自左向右 单目 用于限定全局标识符 类型名 变量名 函数名等 双目 用于限定类或名字空间的枚举元素 数据成员 函数成员以及类型成员等 双目运算符还用于恢复从基类继承的成员的访问权限 classSTACK structNODE NODE intv STACK NODE NODE intv 自左向右结合在类体外定义数据和函数成员时 必须用双目 限定类的数据和函数成员 以便区分不同类之间的同名成员 63 分为面向对象的作用域 面向过程 C传统 的作用域 面向过程的 词法单位的作用范围从小到大可以分为四级 作用于表达式内 常量 作用于函数内 函数参数 局部变量 局部类型 作用于程序文件内 static变量和函数 作用于整个程序 全局变量 函数 类型 面向对象的 词法单位的作用范围从小到大可以分为五级 作用于表达式内 常量 作用于函数成员内 函数参数 局部变量 局部类型 作用于类或派生类内 数据 函数和类型成员 作用于基类内 数据 函数和类型成员 作用于虚基类内 数据 函数和类型成员 当同一作用域的标识符和类名同名 可以用class struct和union限定标识符为类名 标识符作用域越小 被访问优先级就越高 当函数成员的参数和数据成员同名时 优先访问的是函数成员的参数 面向对象作用域优先于面向过程作用域 64 classPOINT2D intx y public intgetx returnx POINT2D intx inty POINT2D x x this y y 等价于POINT2D y y p 3 5 staticintx 7 voidmain void intx p POINT2D getx 等价于x p getx x POINT2D 4 7 getx 常量对象POINT2D 4 7 作用域局限于表达式 65 4 2名字空间 名字空间可分多次和嵌套地用namespace定义 可以先在初始定义中定义一部分成员 然后在扩展定义中再定义另一部分成员 或者先在初始定义中声明函数原型 然后在扩展定义中再定义函数体 嵌套名字空间可通过定义别名引用 namespaceA intx namespaceB namespaceC intk 4 namespaceAB A B usingnamespaceA B C usingA x usingnamespaceAB A B无成员可用保留字using用于引用名字空间 或者引用名字空间的类型 变量或函数成员 名字空间的非类的函数成员无this 程序或名字空间在引用名字空间成员之前 必须已在名字空间声明或定义了成员 66 namespaceALPHA 初始定义ALPHAexternintx 声明整型变量xvoidg inta g long 声明voidg inta 定义voidg long usingALPHA x 声明引用名字空间变量xusingALPHA g 声明引用名字空间voidg int 和g long 再定义voidg int 在调用时导致二义性错误namespaceALPHA 扩展定义ALPHAintx 5 定义整型变量xvoidg int 定义函数voidg int voidg void 定义新函数voidg void voidmain void g x g 4L 调用函数voidg int 和voidg long g void using之前无该原型 失败 67 名字空间成员三种访问方式 直接访问成员 引用名字空间成员 引用名字空间 直接访问成员 总能唯一地访问名字空间成员 多级名字空间用多个 自左向右访问 引用成员的形式为 using 引用时只给出函数名或变量名 只引用当前声明或定义的部分函数或变量 名字空间扩展定义的新函数或变量没有被引用 在当前作用域内 不能再定义同名的函数或变量 匿名名字空间声明后自动引用成员 优先访问当前作用域定义的同名函数或变量 引用名字空间的形式为 usingnamespace 在当前作用域内 可以定义同名的函数或变量 访问时用单目或双目作用域运算符限定名字或名字空间成员 68 namespaceA intx 1 namespaceB inty 2 namespaceC intz 3 namespace intm 4 intn 6 匿名名字空间usingnamespaceA usingB y intm 7 intz x m n 访问A x z 1 7 6intx y 2 访问B yintv x A x 须用 区分全局x和名字空间成员x inty 4 错误 当前作用域有变量yintmain void returnz 优先访问全局变量 z 69 成员指针 指向类的普通和静态成员的指针 分为普通成员指针和静态成员指针 变量 数据成员 函数参数和返回类型都可定义为成员指针类型 使用普通成员指针访问成员时必须和对象关联 使用静态成员指针时不必和对象关联 普通成员指针通过 和 访问对象成员 和 优先级14级 结合性自左至右 左操作数为类的对象 右操作数为成员指针 左操作数为对象指针 右操作数为成员指针 4 3成员指针 70 普通成员指针是一个成员相对于类体首地址的偏移量 存放的不是成员地址 故不能移动 数据成员的大小及类型不一定相同 移动后指针指向的内存可能是某个成员的一部分 或者跨越两个或多个成员的内存 即使移动前后指向的成员类型正好相同 这两个成员的访问权限也有可能不同 移动指针可能导致越权访问 普通成员指针不能和其它类型互相转换 否则便可以通过类型转换间接实现指针移动 71 structA 普通成员指针是偏移量intm n a 1 2 b 3 4 voidmain void 以下p 0表示偏移 实现时实际0intx A p x b的地址 p 2004 2 4 72 structA struct定义的类 进入类体缺省权限为publicinti f return1 公有成员i f private longj 私有的成员j a voidmain void intA pi 错误 x不能转换为成员指针 73 4 4const volatile和mutable const和volatile可以定义变量 类的数据成员 函数成员及普通函数的参数和返回类型 普通函数成员参数表后出现const或volatile 分别表示this指向对象的 非静态数据 成员不能 在函数体内 修改或是挥发的 注意 非只读类型的静态数据成员可以在函数体内修改 第五章 构造或析构函数的参数表后不能出现const或volatile 构造或析构时this指向对象应能修改且不挥发 静态函数成员参数表后不能出现const或volatile 无隐含this mutable只能用来定义机动数据成员 不能同时加const volatile或static 当整个对象不能被修改时 可以修改其机动数据成员 含const数据成员的类必须定义构造函数 且数据成员必须在构造函数参数表的冒号之后 函数体之前初始化 含volatile mutable数据成员的类不一定要自定义构造函数 74 includeclassTUTOR charname 20 constcharsex 性别为只读成员intwage mutableintquerytimes public T

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论