C++高级语言程序设计第三章_第1页
C++高级语言程序设计第三章_第2页
C++高级语言程序设计第三章_第3页
C++高级语言程序设计第三章_第4页
C++高级语言程序设计第三章_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

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

文档简介

C++高级语言程序设计第三章·C++在非面向对象方面的常用新特性Contents本章内容概览C++高级语言程序设计第三章01C++输入与输出机制02常量定义与函数增强特性03引用机制深入解析04动态内存分配与其他新特性05综合应用与实战案例CHAPTER01C++输入与输出机制从C风格的printf/scanf到C++流式I/O的范式升级Chapter03·I/OStreamC++I/O流基本概念C++用流(stream)的概念统一了输入输出操作,通过iostream库中的cout和cin对象实现类型安全的I/O操作,相比C语言的printf/scanf具有自动类型推导、可扩展性强等显著优势。编程教学场景·C++课堂实践01流的概念:数据在程序与外部设备之间的有序传输序列,C++将输入输出统一抽象为流操作,提高代码一致性与可读性02cout输出流:关联屏幕设备,通过插入运算符<<输出数据,无需格式控制符,编译器自动推导类型03cin输入流:关联键盘设备,通过提取运算符>>接收数据,具备类型自动匹配能力,减少格式化错误04使用前提:程序头部包含#include<iostream>,并通过usingnamespacestd引入标准命名空间C++I/OStreamcout输出流详解cout通过插入运算符<<实现类型安全的链式输出,支持多种数据类型的自动转换与格式化控制,是C++程序向用户传递信息的核心工具。基本输出语法cout<<表达式,支持int、double、char、string等基本类型的自动识别与输出,无需手动指定格式符。编译器根据操作数类型自动选择对应的输出重载函数,实现类型安全的数据传递。auto链式输出一条语句中连续使用多个<<运算符,如cout<<x<<y<<z,编译器按从左到右顺序依次求值。每个运算符返回ostream引用,支持无限级联调用,代码简洁且执行效率高。<<换行控制'\n'仅插入换行符;endl在换行同时刷新输出缓冲区,适用于需要即时显示的场景。频繁使用endl会降低性能,建议在批量输出后统一刷新,平衡实时性与效率。endl格式化输出iomanip库提供setw()控制字段宽度、setprecision()控制浮点精度、fixed设置定点表示法。通过流操纵符实现精细排版,满足报表对齐、科学计数等专业输出需求。iomanipCHAPTER03·INPUTSTREAMcin输入流详解cin通过提取运算符>>实现类型安全的键盘输入,但需注意空白字符截断问题和输入流错误状态处理,掌握getline等辅助函数是处理复杂输入场景的关键。01基本输入语法cin>>变量,编译器根据变量类型自动解析输入内容,无需像scanf那样记忆%d、%f等格式控制符02链式输入cin>>a>>b>>c可在一条语句中读入多个变量,各变量之间用空白字符(空格/Tab/回车)分隔03空白截断问题cin>>遇到空白字符即停止读取,无法直接读入含空格的字符串;应使用getline(cin,str)读取完整一行输入04错误状态处理输入类型不匹配时cin进入错误状态,后续操作失效,需用cin.clear()重置状态并用cin.ignore()清空缓冲区I/OSystemComparisonC++I/O流vsC语言I/O对比C++流式I/O在类型安全性、可扩展性和代码可读性方面全面超越C语言的printf/scanf体系,是C++语言设计哲学'安全优先'的重要体现。LegacyC语言printf/scanf必须手动指定格式控制符(%d、%f、%s等),类型不匹配时编译器不报错,运行时产生不可预期的结果格式字符串与参数列表分离,参数数量或类型不一致时易引发缓冲区溢出等安全隐患不支持用户自定义类型的直接输出,每次新增数据类型都需手动编写转换逻辑类型不安全ModernC++cout/cin流式I/O编译器自动推导变量类型并选择正确的输出/输入方式,彻底消除格式控制符与变量类型不匹配的风险运算符<<和>>可被重载,用户自定义类型只需重载相应运算符即可获得与内置类型一致的I/O体验支持流操纵符(manipulator)进行格式化控制,语法更直观且类型安全,如setw(10)直接设定字段宽度类型安全CHAPTER02常量定义与函数增强特性const常量、函数重载与默认参数——让代码更安全、更灵活Chapter03·Const用const定义常量const关键字为C++提供了类型安全的常量定义机制,相比C语言的#define宏定义具有类型检查、作用域控制和调试友好等优势,是编写安全C++代码的基础。强制初始化·不可修改const声明的常量必须初始化且不可修改,语法为consttypename=value,编译器对任何修改操作直接报错。vs#define宏定义const具有明确的数据类型和作用域,而#define仅是预处理器文本替换,无类型检查,容易引发隐蔽的类型错误。函数参数保护const修饰函数参数(如voidfunc(constint&x))可防止函数内部意外修改实参值,增强接口的安全性和契约性。内部链接属性const对象默认具有内部链接属性(仅在当前文件可见),如需跨文件共享需显式声明为externconst。CHAPTER03·FUNCTION函数的重载(Overloading)函数重载允许在同一作用域中定义多个同名函数,通过参数列表的差异实现编译时多态,使程序接口更统一、调用更直观,是C++静态多态性的基础机制。重载条件同名函数的参数列表必须在参数个数、参数类型或参数顺序上至少有一项不同,编译器据此在调用时选择匹配版本返回值不构成重载函数调用表达式的返回值可能被忽略,编译器无法仅凭返回值类型确定调用哪个版本名称修饰机制编译器通过namemangling将函数名与参数类型编码为唯一内部标识,链接时据此区分不同重载版本典型应用max(int,int)、max(double,double)、max(int,int,int)等多个版本,统一接口名降低使用者记忆负担Chapter3·Functions有默认参数的函数默认参数机制允许在函数声明时为参数预设值,简化了函数调用并减少了重载函数的数量,但需遵循从右向左连续设置的规则,并注意与重载的二义性冲突。01语法规则在函数声明中为参数赋默认值,调用时可省略尾部参数,减少不必要的函数重载定义。02从右连续设置默认参数必须从参数列表最右侧开始连续设置,不允许跳过中间参数进行部分赋默认值。03二义性风险默认参数与函数重载可能产生二义性,编译器在某些调用形式下无法确定调用哪个版本。04编译时绑定默认值在编译时绑定,表达式可为常量、全局变量或函数调用,但不可使用局部变量。CHAPTER03·FUNCTION函数原型(FunctionPrototype)C++强制要求函数在调用前必须有完整的原型声明,使编译器能在编译阶段进行严格的参数类型与数量检查,是模块化编程和多人协作开发的基础保障。01doublesqrt(double)函数原型包含返回类型、函数名和参数类型列表(参数名可省略),如doublesqrt(double),为编译器提供完整的调用检查依据返回类型+参数列表02C++强制要求先声明后调用,未声明的函数调用直接报编译错误,而C语言可能仅给出警告或隐式声明为int返回类型编译期强制检查03.h.cpp函数原型通常放在.h头文件中,函数定义放在.cpp源文件中,实现接口与实现的分离,支持多文件编译和团队协作.h与.cpp分离04constint&constint&参数类型中的const修饰符必须在声明和定义中保持一致,如声明为constint&则定义也必须是constint&const一致性Chapter03引用机制深入解析C++独有的引用概念——从基本语法到函数参数传递的完整掌握Chapter03·References引用的概念与基本语法引用(reference)是C++引入的核心概念,本质上是已存在变量的别名,通过&运算符声明。引用必须在声明时初始化且不可重新绑定,这些约束使其比指针更安全、更直观。声明语法格式为type&ref=var,如int&ref=a,此后ref与a指向同一内存地址,任何对ref的操作等价于对a的操作必须立即初始化引用必须在声明时立即初始化,不允许先声明后赋值(int&ref;是非法的),这保证了引用始终指向有效对象不可重新绑定一旦绑定到某个变量就不可重新绑定到其他变量,ref=b的含义是将b的值赋给ref所引用的对象,而非重新绑定不存在空引用不存在空引用(nullreference),这与指针可以为NULL形成本质区别,使用引用时无需做空值检查,代码更安全FUNCTIONPARAMETERS将引用作为函数参数引用传递是C++函数参数传递的第三种方式,兼具指针传递的高效性与值传递的简洁语法,是C++函数设计的首选参数传递方式。值传递vs指针传递值传递:形参是实参的副本,函数内修改不影响实参,但大对象拷贝开销高。指针传递:需传递地址并用*解引用,语法繁琐且易出错。引用传递机制voidfunc(int&x)形参声明为引用类型(如voidfunc(int&x)),调用时直接传变量名。核心特性:函数内对形参的操作直接作用于实参,无需解引用语法。经典示例swapswap(int&a,int&b)swap(x,y)swap(int&a,int&b):调用swap(x,y)即可交换x和y的值。优势:语法简洁直观,无额外拷贝开销,代码可读性高。const引用传递constType&大型对象(结构体、类对象)应优先使用constType&传递。双重保障:避免拷贝开销的同时,防止函数内部意外修改原始数据。CHAPTER03·POINTER&REFERENCE引用与指针的核心区别指针是存储地址的独立变量,可为空、可重新赋值、有自身内存占用;引用是已有变量的别名,必须初始化、不可重绑定、无独立内存。理解二者区别是正确选择参数传递方式的前提。指针(Pointer)01独立变量,存储目标对象的内存地址,自身占用4/8字节内存,可通过sizeof(p)获取指针本身大小02可以为空(nullptr),可以重新赋值指向不同对象,灵活性高但也带来空指针和野指针风险03访问目标需要解引用运算符*,如*p=10,多级指针(int**)增加语法复杂度引用(Reference)01已有变量的别名,不是独立实体,不占用额外内存(编译器内部通常用指针实现但对程序员透明)02必须在声明时初始化且不可重新绑定到其他变量,天然避免了空引用和悬空引用的问题03使用语法与原始变量完全一致,无需解引用,代码可读性更高,是函数参数传递的首选方式C++·CONSTSEMANTICS常引用与常指针常引用保护数据不可修改,是函数参数最佳实践;常指针按const位置分为指向常量的指针与常量指针,修饰方向决定语义。01常引用constint&ref=a;不能通过ref修改a的值,但a本身可通过其他途径修改;广泛用于函数参数,避免拷贝并保护数据。02指向常量的指针constint*pp指向的内容不可通过p修改,但p本身可重新指向其他地址。const在*左侧修饰所指内容。03常量指针int*constpp本身的指向不可更改,不能指向其他变量,但可通过p修改所指向的内容。const在*右侧。04双重constconstint*constp既不能修改p的指向,也不能通过p修改内容,提供最严格的数据保护。CHAPTER04动态内存分配与其他新特性new/delete内存管理、bool类型、作用域运算符与内置函数Chapter03·Memory动态内存分配:new运算符new运算符是C++动态内存分配的核心工具,自动计算内存大小并返回正确类型指针,支持分配时初始化。相比C语言的malloc,new具有类型安全、语法简洁的优势,但必须与delete配对使用以避免内存泄漏。01基本语法int*p=newint分配单个int大小的堆内存并返回int*指针,编译器自动计算sizeof(int),无需手动指定字节数。newint→int*02数组分配int*arr=newint[n]分配包含n个元素的动态数组,n可以是运行时变量,实现变长数组功能。newint[n]03分配时初始化newint(100)分配并初始化为100,newint[5]{1,2,3,4,5}使用初始化列表为数组各元素赋初值。newint(100)04分配失败处理标准new在内存不足时抛出std::bad_alloc异常,nothrow版本(new(nothrow)int)失败时返回nullptr。std::bad_allocMEMORYMANAGEMENT动态内存释放:delete运算符delete运算符负责释放new分配的堆内存,必须与new严格配对使用。单个对象用delete,数组用delete[],混用或遗漏都将导致未定义行为、内存泄漏或程序崩溃,是C++内存安全的核心纪律。SINGLEOBJECTdeletep释放p指向的堆内存并调用析构函数;释放后应将p置为nullptr避免产生悬空指针(danglingpointer)nullptrARRAYdelete[]arr释放整个动态数组,确保每个元素的析构函数都被调用;若误用deletearr则仅析构首元素全数组MEMORYLEAK内存泄漏new分配的内存未用delete释放,长期运行的程序会耗尽系统内存导致崩溃泄漏DOUBLEFREE重复释放对同一指针执行两次delete导致未定义行为;解决方案是释放后立即将指针置为nullptrUBDATATYPE布尔类型(bool)bool是C++新增的基本数据类型,只有true和false两个取值,为逻辑判断提供了语义明确的类型支持。相比C语言用int模拟布尔值的做法,bool类型显著提升了条件表达式和标志变量的可读性与类型安全性。bool取值与内存只有true和false两个取值,占用1字节内存,语义明确地表达逻辑真/假,替代C语言中用0和非0整数模拟布尔值的做法TRUE/FALSE隐式类型转换bool可与int隐式互转:true转为1、false转为0;非0整数转为true、0转为false,但依赖隐式转换可能引入逻辑歧义隐式互转典型应用场景广泛用于条件判断(if、while、for的控制表达式)和状态标志变量,如boolisFound=false,使代码意图更加清晰状态标志逻辑运算与短路配合逻辑运算符&&(与)、||(或)、!(非)构建复合条件表达式,C++保证逻辑运算的短路求值特性短路求值CHAPTER03·SCOPE作用域运算符(::)作用域运算符::是C++解决名称遮蔽问题的核心工具,允许显式访问被同名局部变量遮蔽的全局变量,也是命名空间和类成员访问的基础语法。01名称遮蔽当局部变量与全局变量同名时,局部作用域内直接使用该名称将访问局部变量,全局变量被遮蔽(namehiding)。NameHiding02显式访问全局变量使用::变量名可显式访问被遮蔽的全局变量,如全局x=100、局部x=200,写::x即引用全局的100。::x03作用域限制作用域运算符只能访问全局变量或外层命名空间/类的成员,不能用于访问外层局部作用域的变量。ScopeLimit04OOP中的广泛应用::用于类外定义成员函数(voidMyClass::func())和访问命名空间成员(std::cout),用途极为广泛。MyClass::func()C++ADVANCED·CHAPTER03内置函数(inline)内置函数通过inline关键字建议编译器在调用处直接展开函数体,消除函数调用开销。它兼具宏替换的效率和普通函数的类型安全,适用于频繁调用的小函数,但编译器有权根据复杂度拒绝内联。编译期内联展开inline关键字声明的函数在编译时可能被直接展开到调用处,避免参数传递和栈帧切换的开销,以空间换时间提升执行效率SPACE↔TIME适用场景函数体简短(通常1-3行)、被频繁调用的函数,如intmax(inta,intb){returna>b?a:b;},调用开销占比大1–3LINES编译器自主决策inline仅为建议而非强制,编译器对包含循环、switch、递归等复杂结构的函数通常忽略内联请求,按普通函数处理SUGGESTIONONLY优于#define宏内联函数具有类型检查、支持调试、可访问类私有成员,避免了宏替换的副作用和调试困难TYPESAFEChapter03·CommentsC++的注释风格C++在C语言的块注释/**/基础上新增了行注释//,提供更便捷的单行注释方式。两种注释风格各有适用场景,合理使用注释是编写可维护代码的重要实践。行注释//从双斜杠开始到行末自动结束,无需配对闭合符号,避免了块注释忘记*/导致的跨行错误,是最常用的注释方式//块注释/**/可跨越多行,适合长段说明或临时禁用大段代码,但需注意不可嵌套使用/**/最佳实践解释"为什么这样做"而非描述"代码在做什么",好的代码本身应能清晰表达逻辑,注释补充设计意图和背景Why>What文档生成Doxygen等工具通过特定注释格式(如///和/***/)从源码自动提取API文档,是大型项目的标准实践DoxygenCHAPTER05综合应用与实战案例通过素数判断、数组操作和综合项目将本章新特性融会贯通CASESTUDY案例一:素数判断程序素数判断是经典的循环与分支综合练习,通过for循环遍历可能的因子并用break提前终止,体现了C++基本控制结构的协同运用,同时为后续的算法优化提供了对比基线。算法逻辑从2到n-1逐个试除,若n%i==0成立则说明n有非平凡因子,用break立即跳出循环,避免不必要的计算。这种线性搜索策略直观易懂,适合初学者理解循环控制的基本原理。for+break结果判定循环结束后若i==n说明所有可能的因子都不能整除,n为素数;若i<n则说明中途break,n不是素数。这一判定逻辑简洁高效,充分利用了循环变量的最终状态。i==n输入输出使用cin接收用户输入的整数n,用cout输出判断结果,体现了C++流式I/O的简洁语法。标准输入输出是程序与外界交互的基础,本案例展示了最基本的I/O操作模式。cin/cout代码结构清晰展示了for循环、break语句、if条件判断和流式I/O的综合运用,是本章基础知识的典型集成案例。程序结构层次分明,便于学生理解各组件的协作关系。综合集成PRIMEOPTIMIZATION案例一优化:高效素数筛选将素数判断的试除上界从n优化到√n,时间复杂度从O(n)降至O(√n),是算法优化的经典示范。扩展到批量输出时,双层循环结构展示了嵌套控制流的应用。优化原理若n有因子d>√n,则n/d<√n必为另一因子,因此只需试除到int(sqrt(n))即可判定,大幅减少循环次数O(√n)实现要点需要#include<cmath>引入sqrt()函数,循环上界改为intn=sqrt(k),将时间复杂度从O(n)优化到O(√n)sqrt()批量输出外层for循环遍历k从2到100,内层循环对每个k执行优化后的素数判定,是双层循环嵌套的典型应用双层循环进阶扩展可使用埃拉托斯特尼筛法,用bool数组标记合数,适合更大范围的素数批量求解筛法CASESTUDY·参数传递案例二:三种参数传递方式对比通过swap交换函数的三种实现方式对比,直观展示值传递、指针传递和引用传递在语法简洁性、执行效率和实参修改能力上的差异,验证引用传递作为C++首选方案的优势。PASSBYVALUE值传递函数签名voidswap(inta,intb),形参是实参的拷贝,函数内交换只影响副本,调用后实参x和y的值不变。适用于只需读取参数值、不需修改实参的场景,但对大型结构体或类对象会产生显著的拷贝开销。无法交换PASSBYPOINTER指针传递函数签名voidswap(int*a,int*b),调用时需写swap(&x,&y)传地址,函数内用*a和*b解引用访问实参。能成功交换实参值,但取地址和解引用增加了语法复杂度,且存在空指针风险。繁琐可换PASSBYREFERENCE引用传递函数签名voidswap(int&a,int&b),调用时直接写swap(x,y),函数内a和b就是x和y的别名,语法最简洁。兼具指针传递的效率和值传递的简洁,无拷贝开销、无空引用风险,是C++函数参数传递的推荐方式。推荐首选CASESTUDY·动态内存管理案例三:动态数组的创建与使用动态数组案例展示了new/delete在实际编程中的完整使用流程:根据运行时需求分配内存、填充和处理数据、最后正确释放并置空。掌握这个流程是避免内存泄漏和悬空指针的基本功。STEP01·ALLOCATEint*arr=newint[n]数组大小在编译时未知,需根据用户输入的n值运行时确定,使用int*arr=newint[n]创建变长动态数组newint[n]STEP02·FILLnewint[n]{...}通过循环和cin依次输入n个元素存入arr[i],也可在分配时用初始化列表newint[n]{...}直接赋值cin>>arr[i]STEP03·RELEASEdelete[]arr使用完毕后必须执行delete[]arr释放整个数组内存,然后将arr置为nullptr防止后续误用悬空指针delete[]STEP04·LIFECYCLEnew分配→读写操作→delete[]释放→指针置空,四个步骤缺一不可,是C++内存管理的标准范式4步范式CaseStudy04函数重载实战——多版本max通过max函数的三个重载版本展示函数重载的实际应用价值:统一的接口名称、自动的版本匹配、降低使用者记忆负担。编译器根据参数类型和数量在编译期确定调用目标,实现静态多态。Overload01intmax(inta,intb)接收两个整数,返回较大值;调用max(3,5)时编译器匹配此版本,返回5max(3,5)→5Overload02doublemax(doublea,doubleb)接收两个浮点数,返回较大值;调用max(3.14,2.71)时匹配此版本,处理小数比较max(3.14,2.71)Overload03intmax(inta,intb,intc)接收三个整数,内部复用两参数max实现max(a,max(b,c)),展示重载版本间的协作max(a,max(b,c))Compiler名称修饰与符号匹配编译器通过名称修饰将三个max编码为不同内部符号(如max_ii、max_dd、max_iii),链接时精确匹配max_ii/max_ddCHAPTER03·SUMMARY本章知识体系总结第三章构建了C++在非面向对象方面的完整新特性体系:I/O流提供了类型安全的输入输出,const和函数增强提升了代码安全性与灵活性,引用机制奠定了参数传递基础,动态内存分配赋予了运行时资源管理能力。SECTION01核心机制(重点

温馨提示

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

评论

0/150

提交评论