还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
语言中的函数C数语组实现块础过数函是C言的重要成部分,是程序模化的基通函,们复杂为码块个码块负我可以将的程序分解更小、更易管理的代,每代责务完成特定的任为什么要学习函数?提高代码复用性简化程序结构便于调试和修改数许们复码过复杂务为个数们函允我将重使用的代段封装通将任分解多函,我编条起来,只需写一次,却可以在程序的可以使程序更加清晰、有理,便于理调这减码维护个数专项不同部分多次用大大少了代解和每函注于完成一特开发务结构块冗余,提高了效率定任,使整体更加模化函数的基本概念定义特性数个务数隐实现细函是一独立完成特定任函具有封装性(藏码块它节单测的代,是程序中的基本)和独立性(可独构单个数试它许员复杂问建元每函都有明确),允程序将输预输题为单的入和期的出,使程序分解更小的、可管理的结构块更加化和模化元优势语言函数的基本结构C返回值类型数数类指定函返回据的型函数名数标识函的唯一符参数列表数输数函接收的入据函数体务码块完成特定任的代主函数的特殊性main程序入口点返回值约定个须数类每C程序必有且只有一main函通常返回int型个数它执值结main函,是程序,返回0表示程序正常编译值发错误行的起点器会首先束,非0表示生查执数这个值找并行main函返回可以被操作系统执状用来判断程序的行态命令行参数函数的声明(声明与定义的区别)函数声明编译数称数类类数声明向器提供函的名、参型和返回型,但不包含函实现它诉编译这个数义体告器函存在,将在其他地方定函数定义义数实现数数执定包含完整的函,包括声明部分和函体函体是行特务码块内定任的代,包含在花括号关系个数头义一函可以被声明多次(通常在文件中),但只能被定一次数编译义则实际实声明用于在使用函之前告知器其存在,而定提供的现码代函数声明的语法返回类型函数名参数类型1参数名1,参数类型2参数名2,...;//示例int addint a,int b;float calculate_areafloat radius;void print_messagechar*msg;数编译够够处数调函声明向器提供了足的信息,使其能正确理函用在声明数选数码读中,参名是可的,但包含参名可以提高代的可性声明通常以分号结这个义束,表示只是一原型,而非完整定数头该数开头函声明通常放在文件(.h文件)中,或者在使用函的源文件部较个时数为它编译够分当程序大,分布在多源文件,函声明尤重要,使器能数义现处该数调在函定出之前就能理对函的用函数定义的语法返回类型数数类函将返回的据型(int、float、void等)函数名和参数列表数标识它输数函的符和接收的入参函数体语执务用花括号{}括起来的一系列句,行具体任语句return数值则语结如果函有返回,使用return句返回果数义数须数类数数函定中的参列表必包含参型和参名,而函体包含完成特定任务码语数义结个的所有代句与声明不同,函定不以分号束,而是以一完整的码块现代形式出函数调用准备参数数备传递给数实际数这数类根据函声明,准好需要函的参些参的应数数类型与函声明中的参型匹配执行调用数内数调数转使用函名加上括号的参列表来用函程序流程会调数数开执至被用函的函体始行处理返回值数执毕调带值函行完后,会返回到用点,并回返回(如果有话调这个值进续的)用者可以使用返回行后操作数调时权暂时从数转调数执调函用,控制会当前函移到被用函,行完被数调继续执这块用函后再返回用点行是程序模化的核心机制,使程序够为单能分解可重用的独立元举例简单求和函数函数分析//函数定义int suminta,int b{这个简单数个数数计它们结的求和函接受两整参,算的和,并返回果int result;数义它个类数个类值函定明确指出接受两int型参,并返回一int型result=a+b;数们个变它们为实传递给return result;在main函中,我声明了两量x和y,并将作参数数计它们这个值赋给变}sum函sum函算并返回的和,返回被total量,过数显然后通printf函示出来//在main函数中调用这个数义调值处例子展示了函的基本用法定、用和返回的理,是理解Cint main{语数言函机制的良好起点int x=5,y=10;int total;total=sumx,y;printf总和:%d\n,total;return0;}函数返回值返回类型语句return须数义时必在函定和声明明确指定值给调用于将返回用者数类义类可以是任何基本据型或自定数语结执函遇到return句后立即束行型使用方式类型转换赋值给变值动转换为类可以直接量返回会自声明的返回型达条语导损数可以用在表式或件句中可能致精度失或据截断无返回值函数void函数定义应用场景语句使用void return值数为类数执输数带值无返回函使用void作返回void函常用于行打印出、更新在void函中,可以使用不的该数值给调数结构设备值语结数执型,表示函不会返回任何据、控制等不需要返回return句提前束函行,如这类数执单缓带值语用者函通常用于行某些操的操作比如打印菜、清空冲return;但不能使用的return结屏显务这导编译错误作而不需要返回果区、更新幕示等任句,如return0;会致虽数值它们过数传递响状态别针数时够调环变值数然void函不返回,但可以通参影程序,特是使用指参能修改用境中的量因此,void函仍然是程序中强大的工具函数参数概念参数作用数执输数提供函行所需的入据参数特性类数顺须数型、量、序必匹配函声明参数传递语认值传递C言默使用机制数数数过数数调数这数执语数类函参是函与外部世界交流的通道,通参,函可以接收来自用者的据并基于些据行操作C言中,参的须数义时数传递时应数类规则型必在函声明和定明确指定,参会遵循对的据型数调时实际数值复数这内这数数关当函被用,参的会被制到形式参中,两者在存中是独立的了解一点对正确使用函参至重要,特别调环变值况是在需要修改用境中量的情下形参与实参的区别形式参数(形参)实际参数(实参)数义时变传数它实数调时传递给数值变它们形参是在函定声明的量,用于接收入的据参是在函用函的具体或量可以们数义内类数变达数调结在函定的括号列出,包括型和参名是常量、量、表式或函用的果数内数变数调实数响它们调数环形参只在函部有效,是函的局部量当函被用参的作用域不受函影,存在于用函的境时内数执毕销数调时实值复给应,形参会被分配存,当函行完后,形参会被中在函用,参的会被制对的形参毁参数传递方式概述值传递(传值调用)值传递语认数传递调数时实值复给是C言的默参机制用函,参的被制形内数内响参,两者在存中是独立的因此,在函部对形参的修改不会影到实值原始参的简单数类
1.适用于据型(int、float等)数内响调环
2.函修改不影用境数复导开销
3.据制可能致性能地址传递(引用调用)过传递变内针实现数数通量的存地址(指)函接收的是指向原始据的指针过数值,因此可以通解引用操作直接修改原始据的调环变值
1.可以修改用境中的量数结构复开销
2.适用于大型据,避免制过针间访问数
3.需要通指接据值传递举例执行过程分析void modifyint num{num=num*2;//修改仅在函数内有效这个变值传递给数数内在例子中,量x的10被函modify在函部,形printf函数内部:%d\n,num;这个值数时它变参num接收了的副本当函修改num,只是改了自己}内变值变部的副本,而原始量x的保持不输结int main{出果int x=10;•调用前:10printf调用前:%d\n,x;数内•函部:20•调modifyx;//传递x的值用后:10这值传递数内数响调printf调用后:%d\n,x;清楚地展示了的特性函部对参的修改不会影到环数//x的值保持不变,仍为10用境中的原始据return0;}地址传递举例执行过程分析void swapint*a,int*b{int temp=*a;这个经换数传递数个典的交函演示了地址的强大功能函swap接收两整*a=*b;针为数这针数变型指作参,些指指向main函中的量x和y*b=temp;过数访问变}通解引用操作(*a和*b),swap函可以直接和修改原始量值执换这数为数的行交后,些修改保留在main函的作用域中,因函操数int main{作的是原始据本身,而不是副本int x=5,y=10;这种数够个值数结构复机制使得函能返回多,或修改大型据而无需制printf交换前:x=%d,y=%d\n,x,y;个结构整,提高了程序的效率swapx,y;//传递x和y的地址printf交换后:x=%d,y=%d\n,x,y;//值成功交换,x=10,y=5return0;}函数嵌套调用主函数调用第一层函数第二层函数返回流程从数开执调数数内调数数程序main函始行main用函A函A部用函B函B完成后返回A,A完成后返回main数调个数内调个数数调数时数执暂权转数数执毕权数函嵌套用是指在一函部用另一函当函A用函B,函A的行会停,控制移到函B函B行完后,控制返回到函继续执A中断的地方行调构复杂数层结构个数专务块维护统栈结构数调链个数嵌套用可以建的函次,每函注于特定任,使程序更加模化和易于系使用来跟踪函用,保存每函的局部变数执毕调量和返回地址,确保函行完后能正确返回到用点递归函数初步定义终止条件数间调须况递归函直接或接用自身必有基本情停止执行机制递归情况数调栈状态问题为问题利用函用保存将分解更小的子递归种决问题别为问题务环递归优观是一解的强大方法,特适合那些可以分解相似子的任与迭代(循)相比,通常提供更雅、更直的决树结构图历问题解方案,尤其是对于、形遍、分治算法等递归递归调栈间导额内开销栈险实际应然而,也有其成本每次用都会在上分配新的空,可能致外的存和潜在的溢出风因此,在用中权递归优需要衡使用的缺点递归函数案例阶乘——递归执行流程//递归实现阶乘函数int factorialintn{计过算factorial5的程//基本情况终止条件if n=1{
1.factorial5=5×factorial4return1;
2.factorial4=4×factorial3}
3.factorial3=3×factorial2//递归情况调用自身else{
4.factorial2=2×factorial1况return n*factorialn-1;
5.factorial1=1基本情}从况开基本情始回溯}
1.factorial2=2×1=2int main{
2.factorial3=3×2=6intnum=5;printf%d的阶乘是:%d\n,
3.factorial4=4×6=24num,factorialnum;
4.factorial5=5×24=120return0;阶因此,5的乘等于120}递归函数的注意事项必须有终止条件递归深度限制递归数须个个况终条递归递归调栈间递归导栈函必包含一或多基本情(止件),确保每次用都会在上分配新的空,太深可能致空终条导递归终栈间语递归统栈为在某一点停止缺少止件会致无限,最造成溢出耗尽C言中,深度通常受限于系大小,一般几错误层千至几万性能考量尾递归优化递归导复计优数递归递归递归调数个编译优可能致重算(如未化的斐波那契列),增加尾(用是函的最后一操作)可以被某些器计负关键应备录减栈编递归数时递归不必要的算担在性能的用中,可能需要使用忘、化,少使用写函,尽可能使用尾形式以提动态规划递归转换为实现或将迭代高效率语言内置库函数与自定义函数C标准库函数自定义函数语标库数输输处义数员编数它们C言提供了丰富的准函,涵盖入/出、字符串自定函是程序根据特定需求自行写的函可数计内个领这数经预编执标库务复杂逻辑理、学算、存管理等多域些函已先以行准不直接提供的特定任,或者封装以优码读复写和化,可以直接在程序中使用提高代可性和用性•输输•业务逻辑处入/出printf,scanf特定理•处•义数结构字符串理strlen,strcpy自定据操作•数数•实现学函sqrt,pow算法•内存管理malloc,free•接口抽象和封装如何使用库函数链接正确的库调用函数并处理返回值库数数库了解函数原型有些函(如学)可能需要档调数编译时显链包含相关头文件按照文中的格式正确用函,在式接,例如使用-lm库数应查阅档处值许库数选项链数库数标库在使用函前,文了解并适当理其返回多函接学大多准函库数应数类值标错误码值数动链处使用函的第一步是包含相的其参型、返回和用法准返回代或特殊来指示操作会自接,无需特殊理头这头数库数为义结应检查这值文件,些文件包含函的声函的行是明确定的,正确果,程序些返回以确它们数调明例如,使用printf需要包含理解的使用方式非常重要保函用成功数数stdio.h,使用学函需要包含math.h自定义函数的使用流程设计函数声明函数数数值数明确函功能、参和返回在使用前提供函原型调用函数定义函数该数实现数码在程序中使用函函体的具体代项义数还块划编译链数头义则这种在多文件目中,自定函的使用涉及模分和接函声明通常放在文件.h中,定放在源文件.c中分离数够个时实现隐使得函能在多源文件中被重用,同保持的藏性数设计应单职责则个数负责个务数应该简洁数值类应良好的函遵循一原,一函只一明确的任函接口明了,参和返回型当一致且易于理释编质义数解适当的注和命名也是写高量自定函的重要部分变量作用域全局作用域数义变在所有函外部定的量文件作用域个内变限定在一源文件的量函数作用域数数数内变函参和在函声明的量块作用域复语块内变在合句或声明的量变决它语变关类称量的作用域定了在程序中的可见性和生命周期C言中,量的作用域与其声明位置密切相理解不同型的作用域对于避免名冲突、管内资设计结构关理存源和清晰的程序至重要规则变访问数错误设计应变围内这样作用域控制了量的可性,防止不必要的据共享和潜在的良好的程序当限制量的作用域,只在必要的范使用,可以复杂维护降低程序的性,提高可性局部变量定义特点存储特性优势与使用场景变数码块内变认为动储类别变数局部量在函或代部声明,局部量默自存使用局部量有助于封装据,防止仅它数块内数调时创数它们临时其作用域限于声明的函或(auto),在函被用建,函外部函意外修改适用于开这个围变访数时销数调创计环计数储间部离范,量就不再可返回毁每次函用都会算、控制循的器、存中问变储栈变实值结场局部量存在上,其生命周建新的量例,保存不同的如果等景由于作用域有限,相同数执变义称变数期与函的行期相同果未初始化,局部量包含未定的名的局部量可以在不同函中使值用而不冲突全局变量定义特点生命周期使用注意事项变变变应谨慎全局量声明在所有全局量的生命周期全局量使数时间过赖导函外部,通常位于与程序运行相用,度依会致开头它们从启动难维源文件的同,程序一直程序以理解和个续结它护它们数的作用域延伸到整持到程序束破坏了函们储数源文件,如果使用存在据段而非的封装性,增加了函关键栈显数间隐赖extern字声明,上,如果未式初的式依最还扩个动变数可以展到多源始化,会被自初始好限制全局量为文件化零量,并使用明确的命约名定局部变量与全局变量重名局部优先原则#include变变时内变变这该当局部量与全局量同名,在局部作用域,局部量会遮蔽同名的全局量意味着在//全局变量访问变变作用域中的所有未限定的引用都会局部量,而不是全局量int value=100;这种称为称变语规则它许数变机制名遮蔽或量遮蔽,是C言作用域的重要部分允函使用与全局称状态void test{量相同的名,而不会意外地修改全局//局部变量,与全局变量同名为编实践称变约避免混淆,良好的程是避免使用相同名的局部和全局量,或者采用明确的命名定来区int value=200;它们分//访问局部变量printf局部value:%d\n,value;//使用作用域解析操作符访问全局变量//注这是非标准扩展,不是所有编译器支持//printf全局value:%d\n,::value;//标准方法使用单独的变量名int globalValue=::value;printf全局value:%d\n,globalValue;}int main{printfmain开始时全局value:%d\n,value;test;printfmain结束时全局value:%d\n,value;return0;}静态变量在函数中的作用static内存持久性作用域限制状态保持关键变态变变态变数调使用static字声明的局部量在函尽管静局部量的生命周期与全局静局部量的主要用途是在函用数调结值它们它间状态数用束后仍然保留其在程量相同,但其作用域仍然限制在声明之保持信息例如,跟踪函被开执时数内这数调数缓计结序始行初始化一次,之后保持存的函意味着其他函无法直接用的次、存上一次的算果或结这变访问这个变数维护内状态在,直到程序束与普通局部量量,保持了据封装性部机数调时创时销每次函用建,返回毁的行为不同态变结变变实现级编单懒载记忆静局部量合了全局量的持久性和局部量的封装性,是某些高程模式(如例模式、加、化)的重要工具函数的存储类别autostatic认变储类别块内创默的局部量存,在1态变值数级块结时销关键静量保持其,函static限制可建,束毁字auto通常被2级为内见性,文件static限制文件可见省略registerextern4编译变储义变提示器将量存在寄存器中以加声明在其他位置定的量,用于在多3访问现编译个间变快代器通常会忽略此提文件共享全局量示储类别决变时间这内数关存指定符定了量的作用域(可见性)和生命周期(存在)理解些指定符对于有效管理存和控制据可见性至重别项要,特是在大型目中标还关键创线储个线变标C99准引入了thread_local字(_Thread_local),用于建程局部存,即每程有自己的量副本C11准将其重为义命名_Thread_local,并在threads.h中定了宏thread_local函数(标准)inline C99内联函数的目的//在C99中声明内联函数inline int maxint a,int b{内联数优关键员函的主要目的是化性能使用inline字,程序可以return aba:b;议编译数调换为数码数调开销建器将函用替函体代,消除函用,如}数压栈转参、跳和返回等操作适用场景//在使用inline函数的文件中必须提供定义//或者使用extern inline声明内联数简单频调数这类数调函最适合小型、且繁用的函对于函,开销过数执时间访问设//使用示例用可能超函本身的行常见例子包括器/置器数简单数条检查函、的学运算和件int main{注意事项int x=5,y=10;int result=maxx,y;//可能被内联内联编译议编译它过内联printf较大值:%d\n,result;只是对器的建,器可能忽略度使用可能导码胀递归数复杂数return0;致代膨,反而降低性能函和包含控制流的函内联}通常不适合函数指针基础函数指针定义数针数数针它储数许函指是指向函而非据的指存函的入口地址,允在运时选择调哪个数行用函声明语法类针数类型*指名参型列表;例如int*pFuncint,int;函数指针赋值数显选pFunc=函名;//式取地址(可)数隐转换pFunc=函名;//式(常用)通过函数指针调用函数数数显*pFunc参1,参2;//式解引用数数隐调pFunc参1,参2;//式用(C99后支持)函数指针应用回调函数函数表插件与模块化设计数针应实现调数针数组创数查实数针构动函指最常见的用是回机制,函指可以建函找表,函指支持插件式架,程序可以数为数传递给个数现类状态态载块访问数这种设即将函作参另一函似分支或机的功能相比大量加模并其中的函标库数它语数灵计统够开发准中的qsort函是典型例子,if-else或switch句,函表提供更使系的各部分能独立和更新,个较数针许户扩别处扩维护接受一比函的指,允用自活、可展的方案,特是在理命令增强了程序的可展性和性义规则发处时定排序分或事件理数针实现编态为关键它们许码数实现况数签数类类函指是泛型程和多行的机制,允代在不知道具体函的情下工作,只要函名(参型和返回型)匹配这种灵语够实现许语即可活性使C言能多面向对象言的特性可变参数函数可变参数机制#include#include语过头处变数数这数够数数C言通stdarg.h文件提供了理可量参的机制一功能使函能接受不确定量的参,如标数printf和scanf等准函所示//可变参数函数声明变数数关键组int sumintcount,...;可参函的件•储数类va_list用于存参信息的型int main{•变个变数//调用可变参数函数va_start初始化va_list量,指向第一可参•获数个int total1=sum4,10,20,30,40;va_arg取当前参并移至下一int total2=sum3,5,15,25;•变va_end清理va_list量变数时数须办数数类过数printf总和1:%d\n,total1;使用可参,函必有法确定参量或型,通常通固定参(如count)或格式字符串(如实现printf总和2:%d\n,total2;printf中的格式指定符)return0;}//可变参数函数定义int sumintcount,...{va_list args;//声明参数列表va_startargs,count;//初始化参数列表int total=0;for inti=0;icount;i++{total+=va_argargs,int;//获取参数}va_endargs;//清理参数列表return total;}可变参数函数实现声明可变参数数变数须个数在函声明中使用省略号...表示可参部分必至少有一固定参在省略号之前,用于va_start的参考点例如int printfconstchar*format,...;使用处理参数va_list数内类变储数过它在函部,使用va_list型量存参信息,并通va_start初始化个数变个数va_start接受两参va_list量和最后一固定参名提取参数值顺访问个变数个数使用va_arg宏按序每可参va_arg需要两参va_list变数类它数值针动个量和当前参的型返回当前参的,并将指移到下一参数清理资源处数调释资这理完所有参后,用va_end宏放va_list可能使用的源一内问题步在某些平台上是必需的,以防止存泄漏或其他函数返回结构体返回结构体的优势#include过数结构们从数获个关值仅单值这复通函返回体,我可以函中取多相的,而不限于一返回对于需要返回//定义日期结构体数况标合据的情非常有用,如日期、坐、配置等typedef struct{实现机制int year;int month;数结构时它创个临时给调这结构数复结构int day;当函返回体,会建一副本并返回用者涉及体据的制,对于大型导开销为这种开销时针数为}Date;体可能致性能了避免,有候会使用指或引用参作替代方案注意事项//返回结构体的函数义结构针为数变内释Date createDateinty,intm,int d{返回本地定的体指是不安全的,因当函返回后,局部量的存将被放如果需要返回指针应动态内态变内责Date newDate;,使用分配的存或静量,并明确存管理任newDate.year=y;newDate.month=m;newDate.day=d;return newDate;}int main{//调用返回结构体的函数Date today=createDate2023,6,15;//使用返回的结构体printf日期:%d年%d月%d日\n,today.year,today.month,today.day;return0;}函数的不完全声明与隐式声明隐式声明问题标准变化标调标隐数在早期的C准中,如果用未声明的C99准后,式函声明已被禁止,数编译该数类编译须数调发错函,器会假定函返回int器必对未声明函的用出数这种隐误这变开发型并接受未指定的参式声一化强制者提供正确的函导严类问题别数码类明会致重的型安全,特声明,提高了代的型安全性和可实际数义隐设是当函定与式假不匹配靠性时不完全声明数类数虽不完全声明指定了函名和返回型,但省略了参信息(如void fun;)然在许这实践为它许编译验证数类C90中允,但仍然不是好的,因不允器参型匹配为隐关问题应养数习惯现项防止式声明和相,成在使用函前明确声明的在代C目中,通数头数这头常将函声明放在文件中,并在需要使用函的源文件中包含些文件头文件与函数声明头文件角色数集中管理函声明和接口头文件包含使用#include将声明引入源文件头文件保护导错误防止多重包含致的项头组织数标头结构义数义它们个在多文件目中,文件是和共享函声明的准方法文件通常包含定、函原型、宏定等,使可以在多过应头获这编译链时源文件中共享源文件通包含相的文件取些声明,然后器在接解析所有引用头护过预处实现头内复类变义导文件保机制(通#ifndef,#define,#endif理指令)确保文件容不会被重包含,避免由于型或量重定编译错误项组织头结构维护码关致的在大型目中,良好的文件对于代的一致性和可理解性至重要函数的递归优化尾递归尾递归概念//普通递归实现阶乘int factorialintn{递归递归种递归调数执个尾是的一特殊形式,其中用是函行的最后一if n=1return1;没计赖递归结这种许编译进调操作,且有其他算依果形式允器行尾return n*factorialn-1;优递归转换为用化,将迭代形式}优化机制//尾递归实现阶乘递归数调帧递归编译复在尾中,当前函用在前不再需要,因此器可以int factorial_tailint n,int result{栈帧为递归帧这显减内用当前,而不是每次分配新著少了存使用,if n=1return result;栈险避免了溢出风return factorial_tailn-1,n*result;实现技巧}递归转换为递归额数传递//对外接口,隐藏初始累加器将普通尾通常需要引入外参(累加器)来中间结这数储计结终递归调额int factorial_optimizedint n{果些参存了部分算果,使最用无需外操结return factorial_tailn,1;作即可得到完整果}内联函数与宏的区别类型检查参数求值内联数类检查数类简单内联数数值数数函提供完整的型,确保参型正确宏是的函中参只求一次,与普通函相同宏中的参在展换没类检查导为编译错误开时值导问题文本替,有型,可能致意外行或可能被求多次,致副作用(如自增操作在宏中多次执行)调试支持复杂表达式内联数数样调试单执设内联数复杂逻辑环条语虽实函可以像普通函一,支持步行和断点置函可以包含,如循和件句宏然也能开预处阶调试难内执现复杂逻辑码读较错宏展在理段完成,工具以直接跟踪宏部的行,但通常需要特殊技巧,代可性差且容易出过程常见函数错误类型返回值问题参数错误记值类数类顺错误忘返回或返回型不匹配参型不匹配或序变导悬针传递针返回局部量地址致垂指不合法的空指作用域问题递归失控错误访问变终条导递归地超出作用域的量缺少止件致无限变变导递归过栈局部量遮蔽全局量致混淆深度大引起溢出代码案例参数传递错误错误代码修正后的代码//错误代码//正确代码void swapinta,int b{void swapint*a,int*b{int temp=a;int temp=*a;a=b;*a=*b;b=temp;*b=temp;printf函数内:a=%d,b=%d\n,a,b;printf函数内:a=%d,b=%d\n,*a,*b;}}int main{int main{int x=5,y=10;int x=5,y=10;printf调用前:x=%d,y=%d\n,x,y;printf调用前:x=%d,y=%d\n,x,y;swapx,y;swapx,y;printf调用后:x=%d,y=%d\n,x,y;printf调用后:x=%d,y=%d\n,x,y;return0;return0;}}码错误值传递尝试换个变这换数内响变针数传递数够原始代的在于使用交两量,只会交函的局部副本,不会影原始量修正方法是使用指参(地址),使函能直接修改调变这个数传递用者的量例子展示了理解参机制的重要性代码案例递归溢出栈溢出代码优化后的代码//存在栈溢出风险的代码//迭代实现避免栈溢出int fibonacciintn{int fibonacci_iterativeint n{if n0return-1;if n0return-1;if n=1return n;if n=1return n;return fibonaccin-1+fibonaccin-2;}inta=0,b=1,c;for inti=2;i=n;i++{int main{c=a+b;//对于较大的n,可能导致栈溢出a=b;int result=fibonacci50;b=c;printf结果:%d\n,result;}return0;return b;}}int main{//迭代方法可以处理较大的nint result=fibonacci_iterative50;printf结果:%d\n,result;return0;}递归数仅栈险还复计优记忆缓复计这个说递归虽观总版斐波那契列算法不存在溢出风,有大量重算化方案包括使用迭代算法(如上所示)或添加化存来避免重算例子明了然直,但不是最高效的解决方案充分利用函数提升代码结构用户界面层处户显理用交互和示业务逻辑层实现应核心用功能数据访问层数读管理据写操作数设计块层则创责过划为业务逻辑数访问层层良好的函遵循模化和次化原,建清晰的任分离通将程序分界面、和据等不同次,每包含关数组显码维护扩相的函,可以著提升代的可性和可展性设计数时应关单职责则个数应专项务过杂数应为专在函,注一原,即每函注于完成一特定任大或功能混的函被拆分更小、更注的子函数数间应内实现变响调这种结构码测试维护函之的接口明确且稳定,部可以独立化而不影用者使得代易于理解、和函数测试与调试技巧单元测试调试器使用为个数编专测试验证种输条调试设检查数数变单每函写门的用例,其在各入件下的行使用GDB等工具置断点,函参和局部量,步为测试应况边况错误况数预执码观状态变这问题复覆盖正常情、界情和情,确保函按行代并察程序化有助于追踪根源和理解杂数内期工作函的部工作方式打印调试断言验证关键语输变值执径帮数开处验证数关键检查间在点添加printf句,出量和行路,助追踪程使用assert宏在函始参有效性,在点中虽简单这种调试环状态开发阶帮发现问题发序流程然,但方法在无法使用完整器的境中断言在段助及早,可以在布版本中禁响仍然非常有效用以避免性能影实际项目案例分析模块化结构代码复用设计API图处库为个层数库库设计数处统层级大型像理将功能分解多次据接口了一套通用函理嵌入式系框架提供了两API低数层数层滤镜连务错误处级的函底像素操作函、中接管理、事控制和理,不同API直接控制硬件,高API提供抽象接变换数层复数这种数库实现这应码和函、高合效果函据适配器只需特定的SQL生成口使得用代可以在不同硬件平结构开发级别结数这种设计复码间层实现应使者可以在不同抽象上工和果解析函将重代台移植,只需更改底而保持轻扩统减逻辑变作,并松展系少了80%以上用不学习函数的常见误区忽视函数封装过度依赖全局变量许错误复码过变数间多初学者地将重代度使用全局量会使函个产隐赖码读散布在整程序中,而不是封生式依,降低代可为数这导码测试装函致代冗余、性和可性更好的做法是难维护过数显传递数以且容易引入不一致通参式据,使函决识别复数赖关减性解方法是重模依系清晰可见,并少创数这式,并建函来封装些操副作用作忽略错误处理许义数错误检查处数应验证输多自定函缺乏适当的和理健壮的函数处异况过值状态码传达错误入参,理常情,并通返回或信息,而设不是假一切都会正常工作总结与回顾函数基础1数义调值类设计数函定、用方式、返回型,以及如何清晰的函接口参数传递2值传递传递别实关选择数传与地址的区,形参与参的系,以及如何合适的参递方式变量作用域3变变态变它们响数为数局部量、全局量和静量的特性,以及如何影函的行和访问据高级特性4递归数针内联数变数级概它们应场、函指、函和可参等高念,以及的用景和实现技巧课堂练习与思考题练习实现个递归数计数项实现较种实现异1一函算斐波那契列的第n然后,使用迭代方法相同功能,比两在效率上的差练习编个数针数个数数组数组值值过针数2写一函,使用指参接收一整和其长度,返回中的最大和最小(通指参)题设计个数够类数组进虑数针为较思考如何一通用的排序函,能对不同型的行排序?提示考使用函指作比器与课程结束QA提问时间现开问时间欢关数概应进阶在是放提的,迎提出任何于函念、用或主题问别励课内实际编结问题的疑特鼓就本容与程挑战相合的下节课预告节课们讨语针内这数紧下一我将深入探C言的指与存管理,是与函密关题们习针概动态内相的重要主我将学指的基本念、存分配以及常内问题见的存学习建议议课练习尝试数应您现项阅读建完成今天的后,将函用到有的目中标库数实现帮数设计实践设计准函的可以助理解函的最佳《C程序语题优补言》第4章提供了本主的秀充材料。
个人认证
优秀文档
获得点赞 0