还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
语言程序设计C欢迎学习语言程序设计课程!本课程基于清华大学出版社教材,将系统地介C绍语言的基本概念、语法结构和编程技巧无论您是初学者还是希望提升编C程能力的学生,本课程都将为您提供扎实的语言基础C语言特点与优势C静态类型,过程化可移植性强执行效率高语言是一种静态类型的过程化编程语语言具有极强的可移植性,同一段代码C C言,这意味着变量类型在编译时就已确经过少量修改甚至不需修改,就能在不定,程序执行按照特定的过程顺序进同的硬件平台和操作系统上运行这使行这种特性使得程序员能够精确控制得语言在嵌入式系统、跨平台应用开发C程序执行流程,提高代码可读性和可维中占据重要地位护性语言程序的基本结构C头文件包含使用指令引入所需的标准库和自定义头文件,如#include#include包含标准输入输出库stdio.h主函数main程序的入口点,程序从这里开始执行格式通常为C intmainvoid或int mainint argc,char*argv[]函数体由一对花括号包围,内部包含变量声明和执行语句,每个语句以分号{};结束返回值第一个语言程序C示例代码编译过程Hello,World!这是初学者编写的第一个程源代码首先被预处理器处理,展C序,通过输出来开宏和包含文件,然后被编译器Hello,World!验证开发环境是否正确配置代翻译成汇编代码,最后由汇编器码简洁明了,包含了程序的基和链接器生成可执行文件C本要素运行过程语言开发环境C编译器集成开发环境GCC编译器集合是开源世界、GNU Code::Blocks Visual中最常用的语言编译工具,等提供了代码编C StudioIDE支持多种操作系统平台,提供辑、自动补全、调试、项目管强大的编译优化选项和标准兼理等功能,大大提高了开发效容性率和用户体验文件类型标准输入输出函数函数printf函数scanf格式化输出函数,可显示各种数据类型的值格式化输入函数,从标准输入读取数据•语法格式控制字符串地址列scanf,•语法格式控制字符串参数printf,表;列表;•必须使用符号获取变量地址•返回值为实际输出的字符数格式控制符常见错误整型、浮点型、字符型、字符串%d%f%c%s格式不匹配或缺少符号可能导致程序崩溃•输入溢出问题•可添加宽度和精度控制•缓冲区清理问题•如表示保留两位小数%.2f数据类型概述语言提供了丰富的基本数据类型,用于存储不同种类的数据整型()用于存储整数,适合进行计数和索引;字符型()用C intchar于存储单个字符,常用于字符处理;浮点型包括单精度()和双精度(),用于表示实数float double类型修饰符可以与基本类型组合使用,改变其大小和符号特性常见修饰符包括(缩短长度)、(延长长度)、short longsigned(有符号,默认)和(无符号)选择合适的数据类型对于程序的效率和正确性至关重要unsigned整型数据类型数据类型存储大小最小值最大值字节short int2-32,76832,767字节unsigned short2065,535字节int4-2,147,483,6482,147,483,647字节unsigned int404,294,967,295字节取决于系统取决于系统long int4/8整型数据是语言中最基础的数据类型,用于表示没有小数部分的数值不同的整型变量占用C不同的内存空间,因此具有不同的取值范围程序员应根据实际需要选择合适的整型类型,既能满足数值范围要求,又能节省内存空间需要注意的是,整型数据的具体范围可能因编译器和平台而异,尤其是型在位和long3264位系统上可能有所不同在涉及边界值计算时,应特别留意整型溢出问题实型数据类型(单精度浮点型)(双精度浮点型)科学计数法表示float double占用个字节(位)的内存空间,可占用个字节(位)的内存空间,可语言中可以使用科学计数法表示很大或432864C表示的有效数字约为位型适表示的有效数字约为位很小的实数,格式为或,表6-7float15-16double a.bEn a.ben合存储对精度要求不高的实数,如日常型适合需要高精度计算的场景,如金融示×例如,表示a.b10^n
3.14E2计量数据在科学计算中,型变量计算、科学模拟等在现代系统中,,表示科学float
3145.67e-
30.00567可提高计算速度,但精度有限型已成为浮点计算的默认选择计数法在处理天文数字或微观数值时尤double为有用字符型数据类型编码表型存储扩展字符集ASCII char(在语言中,型变量占用个字节(除了基本的编码外,还有扩展ASCII AmericanStandard Codefor C char18ASCII ASCII)是最基本的位)内存空间,可以存储一个字符虽然和等字符集用于表示更多字符Information InterchangeUnicode字符编码标准,使用位二进制数(型实际上是一种整型,但我们通常将在处理中文等非英文字符时,需要使用支70-char)表示英文字母、数字、标点符号和其用于字符处理字符常量用单引号括起持相应编码的字符类型和函数,比如宽字127控制字符语言中的类型正是基于来,如、、等符类型CcharA9+wchar_t编码设计的ASCII常量与变量常量定义常量是程序执行过程中值不能改变的量,可通过或关键字定义#define const变量定义变量是程序执行过程中值可以改变的量,使用类型名变量名的格式定义命名规则由字母、数字和下划线组成,首字符不能是数字,区分大小写,不能使用关键字常量在程序中起到固定值的作用,可以提高代码可读性和可维护性定义常量的两种主要方式各有特点是预处理指令,在编译前进#define行文本替换;而修饰的变量在编译时进行类型检查,更加安全const变量是程序存储和操作数据的基本单位在语言中,变量必须先声明后使用,且应遵循合理的命名规范好的变量命名能够提高代码的可读C性,如使用有意义的名称、采用驼峰式或下划线分隔的命名风格等关键字和保留字语言常见关键字区分大小写保留字使用限制C语言中的关键字是语言定义的具有特殊语言是区分大小写的语言,这意味着大关键字不能用作变量名、函数名或其他标C C含义的标识符,如数据类型关键字(、写和小写字母被视为不同的字符例如,识符名称尝试这样做会导致编译错误int、等)、控制流关键字(、和是不同的标识符,其中此外,虽然某些标识符(如名为的char floatif Whilewhile main、、等)、存储类关键字是关键字,而可以作为用函数)在当前标准中没有被定义为关键else for while whileWhile(、、等)以及其他关户定义的变量名这要求程序员在编写代字,但由于它们在语言中具有特殊用途,auto staticextern键字(、、等)码时必须严格注意大小写因此最好避免将它们用于其他目的return sizeoftypedef运算符分类算术运算符赋值运算符关系运算符用于执行基本的数学用于给变量赋值,基用于比较两个值,包运算,包括加、减本赋值运算符是等号括等于、不等于+==、乘、除、复合赋值运算符、大于、小于-*/=!=取模以及自增如、、、、大于等于、%+=-=*==、自减运算、等则可以简化小于等于关系++--/=%==符这些运算符是编编码,它们将运算和运算的结果是逻辑程中最常用的基础操赋值合并为一个操值,在语言中表示C作符,支持整数和浮作,提高代码简洁为整数(真)或10点数运算性(假)逻辑运算符用于组合多个逻辑条件,包括与、或、非运算符逻||!辑运算符通常用于条件判断语句中,用来构建复杂的逻辑表达式,控制程序流程算术运算符与表达式基本算术运算符运算优先级语言提供了五种基本算术运运算符优先级决定了复杂表达C算符(加法)、(减式中的计算顺序在语言+-C法)、(乘法)、(除法)中,、和的优先级高于*/*/%+和(取模,求余数)这些和同级运算符按照从左到%-运算符可用于整数和浮点数运右的顺序计算,这称为左结算,但运算符仅适用于整数合性可以使用圆括号改变%操作数默认的计算顺序除法注意事项在语言中,两个整数相除的结果仍为整数,小数部分被截断例C如,的结果是,而不是如果需要得到浮点结果,至少有一5/
222.5个操作数必须是浮点类型,如或的结果是
5.0/25/
2.
02.5赋值与复合赋值运算符基本赋值运算符等号是语言中最基本的赋值运算符,用于将右侧表达式的值赋给左侧=C的变量赋值表达式的值等于赋值后左侧变量的值,这允许多重赋值,如将三个变量同时赋值为a=b=c=00复合赋值运算符为简化编码,语言提供了复合赋值运算符,包括、、、、C+=-=*=/=等这些运算符将算术运算和赋值合并,例如等价于,%=a+=5a=a+5代码更加简洁易读复合赋值还包括位运算的复合形式、、、=|=^=、==表达式求值顺序语言中的赋值是从右到左进行的,在复杂表达式中,必须注意表达C式求值顺序赋值运算符的优先级较低,在包含其他运算符的表达式中,通常最后执行赋值操作当有疑问时,可以使用括号明确表达计算意图自增与自减运算符关系与逻辑运算符比较运算符相等运算符(大于)、(小于)、(大于等=于)、(小于等于)用于数值大小比=(等于)和(不等于)用于比较两==!=较个值是否相等,返回(真)或(假)10逻辑与运算符用于连接两个条件,仅当两个条件都为真时结果才为真,具有短路特性逻辑非逻辑或运算符用于取反,将真变为假,假变为!运算符用于连接两个条件,只要有一真,通常用于否定某个条件||个条件为真,结果就为真,具有短路特性位运算符运算符名称功能说明示例(二进制)按位与对应位都为时结果为110101100=10001按位或对应位有时结果为|111010|1100=1110按位异或对应位不同时结果为^11010^1100=0110按位取反变,变(简化)~0110~1010=0101左移位全部左移,右侧补010102=101000右移位全部右移,左侧补10102=0010符号位位运算符在底层编程和需要高效处理二进制数据的场景中非常有用它们可以用于设置或清除特定位、检查特定位的状态、实现乘除的幂等操作在嵌入式系统、设备驱动程序、图形处理和密码学等领域,位运算是一2项重要技能需要注意的是,位运算需要对二进制表示有清晰的理解,操作不当可能导致意外结果特别是在处理有符号数的右移操作时,不同的编译器可能有不同的行为,这取决于系统如何处理算术右移和逻辑右移类型转换隐式类型转换显式类型转换当表达式中包含不同类型的操作数时,编译器会自动进行类型转显式类型转换,也称为强制类型转换,允许程序员明确指定类型换,以确保计算的一致性这种转换通常遵循向上提升的原转换语法为类型名表达式,如将浮点数转换int
3.
143.14则,即将较小的类型转换为较大的类型,如转为或为整数这种方式可以实现自动转换无法进行的类型转换int longfloat3转为double强制类型转换在处理指针类型时特别常见,如将转换为特void*在赋值操作中,如果右侧表达式的类型与左侧变量的类型不匹定类型的指针但过度使用强制转换可能掩盖潜在的类型不匹配配,也会发生隐式转换例如,将浮点数赋给整型变量时,小数问题,应当谨慎使用,确保转换是安全且有意义的部分会被截断这种自动转换有时会导致精度损失或意外的结果输入输出格式控制格式控制符格式修饰和函数中使用的格式控制符包括格式控制字符串中可以指定字段宽度、对齐printf scanf(整型)、(浮点型)、(字符方式、填充字符等例如表示输出位%d%f%c%5d5型)、(字符串)、(十六进制)、整数,右对齐;表示左对齐;%s%x%-5d%05d(八进制)、(指针)等这些占位表示用填充浮点数可以通过指定小%o%p0%.nf符指定了数据的输出或输入格式数点后的位数•和转换字符之间可以添加标志、宽度、•字段宽度不足时,默认右对齐%精度修饰符•超过指定宽度时,按实际宽度输出•例如表示保留两位小数的浮点数%.2f混合使用注意事项当和混合使用时,需要注意输入缓冲区的处理特别是在连续读取不同类型的数据scanf printf时,缓冲区中的换行符或空格可能导致意外结果清理缓冲区或合理设计输入顺序可以避免这些问题•读取字符时可能受前一次输入的影响scanf•或可用于清理缓冲区getchar fflushstdin程序流程控制结构概览顺序结构最基本的流程结构,按语句编写顺序从上到下依次执行选择结构根据条件选择不同的执行路径,包括和语句if-else switch-case循环结构重复执行某段代码,包括、和循环语句while do-while for程序流程控制是语言编程的核心内容,合理使用这三种基本结构可以构建出任何复杂的算法顺序结构是最简单的流程控制方式,程序按照代C码编写的顺序从上到下逐行执行,没有任何分支或跳转选择结构允许程序根据条件判断结果选择不同的执行路径,通常使用或语句实现循环结构允许程序重复执行一段代码,if-else switch-case常用的循环有、和三种形式,它们适用于不同的场景这些结构可以嵌套使用,构成更复杂的控制流程while do-while for语句if单分支结构最简单的条件判断,只有条件满足时才执行相应代码块条件表达if式条件为真时执行的语句{//}双分支结构根据条件选择两条不同路径条件表达式条件为真时执行的if{//语句条件为假时执行的语句}else{//}多分支结构处理多种可能的条件条件条件为真时执行条if1{//1}else if件条件为真时执行所有条件都为假时执行2{//2}else{//}嵌套结构if在语句内部嵌套其他语句,实现更复杂的逻辑判断嵌套层次过多可if if能导致代码难以理解和维护,应适当使用花括号和缩进保持清晰结构语句switch结构语法使用规则语句作用switch-case break语句是多分支选择结构的另一种形式,语句的表达式必须是整型或字符型在语句中,语句用于终止switch switch switch break适用于针对一个表达式的不同值选择不同执(包括枚举型),不能使用浮点型或字符串结构,跳转到语句后的下一switchswitch行路径的情况其基本语法如下每个后面必须是常量表达式,不能是变条语句继续执行如果省略,程序将case break表达式常量语句量或函数调用多个值可以共用相同的继续执行下一个中的语句,直到遇到switch{case1:1;case case常量语句代码块,实现一对多的映射关系或结构结束,这称为落空现break;case2:2;break;...default breakswitch默认语句分支是可选的,当没有匹配时执行象有时这种特性可以用于多个共享代default:;}case case码,但也容易导致逻辑错误循环while基本语法执行流程循环的基本结构是先判断后执首先计算条件表达式的值,如果为真while行条件表达式循环体(非),则执行循环体一次;然后再while{//0语句条件表达式为真时,重复执行循次检查条件,如此重复,直到条件为假}环体内的语句,直到条件变为假()时停止循环并执行后续代码0终止条件死循环合理设计终止条件是循环编程的关键当循环条件始终为真时,会形成无限循终止条件可以是计数器达到特定值、找环,如或死循while1whiletrue到目标元素、用户输入特定命令等缺环可能是程序错误,也可能是有意设少明确的终止条件可能导致程序异常计,通常需要在循环体内设置跳出条件循环do...while基本语法与特点与循环的区别典型应用场景while循环的基本结构如下循环是先判断后执行,如果初始循环特别适合于需要先执行一do...while dowhiledo...while循环体语句条件表达式条件为假,循环体一次都不会执行;而次操作再决定是否继续的场景常见应{//}while;这种循环的特点是先执行后判断,因此循环是先执行后判断,循环用包括用户输入验证(输入错误时do...while-循环体至少会执行一次,不管条件是否体至少执行一次这是两者最主要的区重新要求输入)菜单驱动的交互式程-为真别序至少需要处理一次的数据处理操作-循环适用于至少需要执行一次在代码结构上,循环的条件表达式do...while while操作的场景,如用户输入验证、菜单驱在循环体之前,而循环的条件例如,实现一个简单的计算器程序,用do...while动的程序等在这些情况下,即使最终表达式在循环体之后另外,户至少进行一次计算,然后询问是否继do...while条件不满足,也需要先执行一次循环语句结束时必须有分号,而语句不续,这时循环就是理想的选while do...while体需要在循环结构后加分号择循环for语法结构循环是最常用的循环结构之一,语法为初始化条件增量循环体for for;;{}执行过程先执行初始化表达式,然后检查条件,条件为真则执行循环体,再执行增量表达式,重复检查条件嵌套循环循环内部可以包含另一个循环,形成嵌套循环结构,常用于二维数组处3理和复杂模式生成循环是语言中最灵活的循环结构,特别适合于已知循环次数的场景它将循环的初始化、条件判断和增量操作集中在语句的开头部分,使代码更加for C简洁清晰循环的三个表达式部分都是可选的,甚至可以完全省略,如表示无限循环for for;;嵌套循环是处理多维数据结构的强大工具例如,一个双重循环可以用来遍历二维数组的每个元素,外层循环控制行,内层循环控制列在使用嵌套for循环时,需要注意控制循环变量的作用域和避免不必要的计算,以提高程序效率循环控制语句语句语句使用注意事项break continue语句用于立即终止当前循环或语句用于跳过当前循环迭代过度使用和可能使程break continuebreak continue语句,程序将跳出循环体,继中的剩余语句,直接进行下一次迭序流程变得复杂难懂一般建议尽量switch续执行循环后的下一条语句在嵌套代在循环中,后会先执通过合理设计循环条件来控制循环,for continue循环中,只能跳出包含它的最内行增量表达式,然后再检查条件;在而不是依赖于和特break breakcontinue层循环常用于提前结束循环,和循环中,别是在维护他人代码时,这些跳转语break whiledo...while continue如在查找操作中找到目标后立即退会直接跳转到条件测试部分句可能成为理解程序逻辑的障碍在出,避免不必要的迭代常用于跳过特定条件下的处必要时使用注释说明跳转的原因和影continue理步骤响与标号goto12语句基本语法适用场景goto语句用于无条件跳转到程序中标记的位置(标虽然常被认为是不良编程实践,但在某些特定场景goto goto号),语法为标号其中标号是一个标识符,后下仍有其价值,如从深度嵌套结构中快速退出、错误处goto;跟冒号定义在程序中的某个位置理和资源清理等3编程规范现代编程中,建议尽量避免使用,而采用结构化C goto编程方法,如函数、循环控制语句和break,continue条件语句,使代码更清晰、可读性更强语句在语言中允许程序无条件跳转到代码中的标记位置,打破了程序的顺序执行流程虽然它提供了编程的goto C灵活性,但过度使用会导致程序结构混乱,形成所谓的意大利面条式代码,使程序逻辑难以理解和维护在一些特殊情况下,可以简化代码,如需要从多重嵌套循环中立即退出,或在函数的多个地方执行相同的清理goto代码但即使在这些情况下,通常也有更好的结构化替代方案如果确实需要使用,应当谨慎规划跳转逻辑,goto并使用清晰的注释说明其目的和作用范围函数概念与作用模块化编程代码重用独立测试函数是语言的基本构函数允许将重复使用函数作为独立单元,C建块,允许将复杂问的代码封装在一个地可以单独测试和验题拆分为更小、更易方,避免代码冗余证,这简化了调试过管理的部分这种模当需要相同功能时,程通过隔离测试每块化方法使程序结构只需调用函数而非重个函数的功能,可以更清晰,便于团队协写代码,这不仅减少更容易地定位和修复作开发,并提高了代了代码量,还使更新程序中的错误,提高码的可读性和可维护和错误修复更加高软件质量性效抽象层次函数创建了抽象层,使用者可以调用函数而无需了解其内部实现细节这种信息隐藏机制降低了系统的复杂性,允许程序员专注于更高层次的问题解决函数定义和声明函数声明(原型)函数声明告诉编译器函数的名称、返回类型和参数列表,但不包含函数体格式返回类型函数名参数列表函数声明通常放在调用函;数之前,或者集中在头文件中函数定义函数定义包含函数的完整实现,包括函数头和函数体格式返回类型函数名参数列表函数体返回值函数体中的{//return;}语句用于返回结果并结束函数执行return函数调用函数调用是使用函数的过程,格式变量函数名实际参数或者=;直接调用函数名实际参数调用时,程序流程跳转到函数体,执;行完毕后返回调用点继续执行实参与形参形式参数实际参数值传递机制形式参数(简称形参)是在函数定义时实际参数(简称实参)是在函数调用时语言中函数参数的传递默认采用值传C声明的参数,它们是函数内部的局部变传递给函数的参数,可以是常量、变递机制,意味着函数得到的是实参的副量,作用域仅限于函数内部形参在函量、表达式或者函数调用的结果实参本,而非实参本身因此,在函数内部数被调用时才分配内存,并在函数调用的计算顺序在语言中是不确定的,因此修改形参的值不会影响主程序中原实参C结束后释放形参的名称可以与主程序不应依赖于特定的计算顺序的值中的变量名相同,但它们是不同的存储实参的个数和类型必须与函数声明中的如果需要在函数中修改主程序中的变单元形参相匹配,否则会导致编译错误或者量,可以通过传递变量的地址(指针)在函数定义中,形参的类型必须明确指运行时错误在函数调用时,实参的值来实现,这样函数就能通过指针间接修定,这是语言强类型特性的体现形参会复制给对应的形参,这种传递方式称改原变量的值这种技术在需要返回多C的数量和类型组成了函数的接口,定义为值传递个结果或修改大型数据结构时特别有了如何与函数进行交互用局部变量与全局变量局部变量全局变量在函数或复合语句内部声明的变量在所有函数外部声明的变量•作用域限于声明它的函数或复合语句内部作用域覆盖从声明点到文件末尾••生命周期仅在函数调用期间•生命周期贯穿程序执行全过程•默认存储类别为,存储在栈上•默认存储类别为,存储在数据段auto external•不自动初始化,含有随机值•自动初始化为零值变量名重名问题使用建议局部变量与全局变量同名时的处理选择合适类型变量的原则•局部变量优先,在其作用域内遮蔽全局变•尽量使用局部变量,降低模块间耦合量•全局变量适用于多函数共享的数据•可使用作用域解析运算符访问被遮蔽的全::局变量•避免过多使用全局变量•避免使用相同名称以减少混淆递归函数递归定义递归是一种函数直接或间接调用自身的编程技术递归函数通常包含两部分基本情况(递归终止条件)和递归情况(将问题分解为更小规模的相同问题)阶乘计算示例阶乘是递归的经典应用×递归实现n!=n n-1!int factorialintn{if n基本情况递归情况=1return1;//return n*factorialn-1;//}斐波那契数列另一个递归典型,其中递归实现Fn=Fn-1+Fn-2F0=0,F1=1int基本情况fibonacciint n{if n=1return n;//return fibonaccin-1+递归情况fibonaccin-2;//}递归注意事项递归虽然优雅,但也有局限性栈空间消耗大,可能导致栈溢出;简单递归可能存在大量重复计算,效率低下,通常可通过动态规划或记忆化搜索优化数组的定义数组基本概念一维数组声明语法数组是一组相同类型元素的集合,这些元素在语言中,一维数组的声明语法为类型C在内存中连续存储,可以通过索引快速访问说明符数组名常量表达式[];数组是最基本的数据结构之一,在语言中C•例如声明一个包int numbers
[10];被广泛使用于数据处理和存储含个整数的数组10•数组元素必须是同一数据类型•常量表达式必须是正整数,表示数组的•数组大小必须是编译时确定的常量大小•数组在内存中占用连续的存储空间•数组大小决定了可存储的元素数量数组初始化方法语言提供多种初始化数组的方式,可以在声明时同时初始化,也可以在声明后逐个赋值C•完全初始化int a
[5]={1,2,3,4,5};•部分初始化剩余元素自动初始化为int a
[5]={1,2};0•省略大小数组大小自动确定为inta[]={1,2,3};3•逐个赋值适用于动态计算的值a
[0]=1;a
[1]=2;数组元素的访问在语言中,数组元素通过索引访问,索引从开始计数访问语法为数组名索引,如表示数组的第一个元素,C0[]array
[0]表示最后一个元素(假设数组大小为)数组索引本质上是一种指针偏移计算,等价于,表示从数array[n-1]n array[i]*array+i组首地址偏移个元素i语言不进行数组边界检查,访问越界会导致未定义行为,可能破坏其他变量或导致程序崩溃常见的数组处理模式包括线性遍历C(使用循环从头到尾处理每个元素)、查找特定元素、累加求和、找最大最小值等掌握这些基本操作是处理数组数据的基础/二维数组字符数组与字符串字符数组基础字符串初始化字符串结束符字符数组是元素类型为的数组,用初始化字符数组的方法有多种空字符(码为)是语言字char\0ASCII0C于存储一系列字符语言中的字符串实符串的结束标志这一设计使得字符串C•使用字符串字面量char str[]=际上是存储在字符数组中的,但有一个操作函数能够确定字符串的结束位置,Hello;重要特点字符串以空字符结尾,而不需要额外的长度信息\0•字符逐个初始化表示字符串的终止char str[]={H,在处理字符串时,必须确保字符数组有e,l,l,o,\0};声明字符数组的语法数组名大足够空间容纳字符串内容加上结束符char[•声明后赋值strcpystr,Hello;小忽略结束符是字符串操作中常见的错误];注意使用字符串字面量初始化时,编来源例如,是char str
[5]=Hello;例如声明一个可存char name
[20];译器会自动添加结束符错误的,因为加上需要个字\0Hello\06储个字符的字符串(加上)19\0符字符串常用操作函数函数函数函数strcpy strlenstrcmp函数返回strcpychar*dest,const charstrlenconst char*str strcmpconst char*s1,const函数用于将源字符串复制字符串长度(不包括结束符)函数比较两个字符串,按*src src\0char*s2到目标字符串,包括结束符它通过计算从字符串开始到遇到第字典顺序返回比较结果如果dest s1s2使用时必须确保目标数组有足一个之前的字符数来确定长度返回正值这是判断字符串相等或\0\0够空间,否则可能导致缓冲区溢这一特性使得处理未知长度的字符排序的标准方法,比单字符比较更出更安全的替代函数是串成为可能,但也要求字符串必须安全有效,它允许指定最大复制字正确终止strncpy符数函数strcatstrcatchar*dest,const char函数将源字符串连接到目*src src标字符串的末尾,相当于字符dest串的加法操作目标数组必须有足够空间容纳结果字符串,包括结束符更安全的替代是,可strncat限制添加的最大字符数指针基础知识指针的概念指针是存储内存地址的变量,指向另一个变量在内存中的位置指针声明格式为类型指针名,如声明一个指向整型的指针*int*p;取地址运算符用于获取变量的内存地址,如将变量的地址赋给指针p=a;a p解引用运算符*用于访问指针指向的变量值,如将指向的变量值设为*p=10;p10指针是语言最强大也最具特色的功能之一,它使程序能够直接操作内存,实现高效的数据处理和动态内存管理通过指针,可以在函数之间传递大量数据而不需要复制数C据本身,只需传递地址;可以实现复杂的数据结构如链表、树等;还可以实现动态内存分配,根据程序需要在运行时申请和释放内存然而,指针的强大功能也带来了风险,如空指针解引用、悬空指针、内存泄漏等问题可能导致程序崩溃或不稳定理解指针的工作原理和正确使用指针是掌握语言的关键C技能,需要通过大量实践和练习巩固数组与指针的关系在语言中,数组名是一个常量指针,指向数组的第一个元素因此数组名和指向数组首元素的指针在许多情况下可以互换使用例如,C对于数组,等价于,都表示数组首元素的地址数组元素可以通过指针算术运算访问,如等价于,int arr
[5]arr arr
[0]*arr+i arr[i]表示访问数组的第个元素i尽管数组名和指针有相似之处,但它们并不完全相同数组名是常量指针,不能被赋予新值;而指针变量可以指向不同的地址此外,运算符应用于数组名时返回整个数组的字节大小,应用于指针时返回指针本身的字节大小(通常是或字节)理解这些差异对于sizeof48正确使用数组和指针至关重要指针与函数指针作函数参数通过将指针作为函数参数,可以在函数内部修改主调函数中的变量值这种方式突破了语言默认的值传递限制,实现了类似引用传递的效果C交换函数案例典型应用是交换两个变量的值void swapint*a,int*b{int temp=调用方式*a;*a=*b;*b=temp;}swapx,y;数组作为参数当数组作为函数参数时,实际传递的是数组首元素的地址函数内部通过指针操作访问和修改数组元素数组大小信息丢失,通常需要额外参数指定数组大小返回指针函数可以返回指针,但必须确保指针指向的内存在函数结束后仍然有效,如静态变量、动态分配的内存或主调函数的变量返回局部变量的地址是危险的做法指向字符串的指针字符指针与字符串指针数组字符串处理技巧指向字符的指针经常用于处理指针数组是元素类型为指针的数组,常使用指针可以实现高效的字符串操作char*字符串与字符数组不同,字符指针自用于存储多个字符串每个数组元素是例如,遍历字符串的典型方式是使用指身不存储字符串内容,而只存储字符串一个指针,指向一个独立的字符串这针递增char*str=Hello;while的地址字符指针可以指向字符数组、种结构在处理命令行参数、多语言文本这种*str{printf%c,*str++;}字符串字面量或动态分配的内存等场景中非常有用写法比使用数组索引更简洁高效初始化字符指针声明和使用指针数组字符串复制、连接等操作也可以通过指char*str=char指向字符串字面量针实现,但必须确保目标内存足够大,Hello;//char*names
[3]={Tom,Jerry,避免缓冲区溢出标准库函数如arr[]=World;char*ptr=arr;Spike};printf%s,names
[0];//指向字符数组输出名称列表、消息表等都可以、内部就是使用指针实现//Tom strcpystrcat用指针数组高效实现的指针的高级应用指向指针的指针函数指针指针的指针(或多级指针)是函数指针指向函数而非数据,指向另一个指针变量的指针,语法较为复杂返回类型*用两个星号声明指针名参数类型列表函数int**pp这种结构允许间接修改指针变指针允许在运行时选择要调用量本身,增加了一层间接引的函数,实现回调机制、策略用多级指针在处理动态二维模式等设计模式,增强程序的数组、多层数据结构等情况下灵活性和可扩展性非常有用二级指针传参当需要在函数内修改指针变量本身(而不仅是其指向的值)时,需要传递指针的指针典型应用包括动态创建链表头节点、动态二维数组分配等二级指针使得函数能够返回多种状态或结果,提高了接口的灵活性结构体类型结构体定义结构体是语言中用户自定义的复合数据类型,可以包含不同类型的数据成员结构体的定义语法为C标签名成员类型成员名成员类型成员名例如,定义表示学生的结构体struct{11;22;//...};struct Student{char name
[50];int age;float score;};结构体变量声明与初始化声明结构体变量的方式完整声明或者在定义时直接声明变量struct Students1;//struct成员列表结构体变量可以在声明时初始化李明Student{//}s1,s2;struct Students1={,也可以通过成员运算符逐个赋值18,
92.5};s
1.age=18;s
1.score=
92.5;结构体成员访问访问结构体成员使用点运算符通过结.struct Students1;s
1.age=18;printf%d,s
1.age;构体指针访问成员使用箭头运算符等价于-struct Student*p=s1;p-age=20;//结构体可以整体赋值复制所有成员*p.age=20struct Students2=s1;//类型重命名typedef关键字可以为类型创建别名,简化结构体使用typedef typedefstruct Student{char name
[50];此后可以直接使用作为类型名等价于int age;float score;}Stu;Stu Stus1;//struct Student这种方式降低了代码冗余,提高了可读性s1;结构体数组与嵌套结构体数组结构体嵌套结构体与指针结构体数组是元素类型为结构体的数组,用结构体成员可以是另一个结构体,形成嵌套结构体经常与指针结合使用,特别是在构建于存储同类型的多个数据记录例如,可以结构,用于表示复杂的数据关系例如,定链表、树等动态数据结构时例如,自引用创建学生数组来存储班级信息义学生结构体,其中包含地址结构体结构体用于链表节点struct struct Node{int个学生的数组指向同类Student class
[40];//40struct Address{char city
[20];char data;structNode*next;//结构体数组可以在声明时初始化型结构体的指针指向结构体的指针可以struct street
[50];int number;};struct};张三通过动态内存分配创建Student class
[3]={{,18,Student{char name
[50];int age;struct Student李四王五嵌套结构体
85.5},{,19,
92.0},{,18,struct Addressaddr;//};*p=struct Student
78.5}};*mallocsizeofstruct Student;联合体与枚举类型联合体(共用体)联合体应用场景枚举类型枚举类型的运用联合体是一种特殊的数据类型,联合体主要用于节省内存空间和枚举是用户定义的整型常量集合,枚举类型在以下场景特别有用允许在同一内存位置存储不同数处理多种可能类型的数据典型提高了代码的可读性和可维护性•表示有限集合的状态或选项,据类型的变量联合体的所有成应用包括枚举定义语法标签名enum如菜单选择、错误代码员共享同一块内存空间,因此同枚举常量列表例如{};enum•变量类型转换,如在不改变一时刻只有一个成员可以有有效•提高代码可读性,用有意义Weekday{Monday,Tuesday,底层位模式的情况下查看整的名称代替魔法数字值联合体的大小等于最大成员Wednesday,Thursday,数的字节构成的大小Friday,Saturday,Sunday};•定义常量集合,比#define•处理消息系统中的不同类型枚举常量默认从开始按序递增,更灵活,具有类型检查0联合体定义和使用union消息也可以显式赋值enum枚举变量声明和使用Data{int i;float f;char enum•在有限内存环境中优化存储Status{SUCCESS=0,str
[20];}data;data.i=10;Weekday today=空间ERROR=-1,PENDING=此时只有成员有效//i data.f=Wednesday;if today==100};此时有效,但的值已联合体与结构体配合使用,可以周末快到了
3.14;//f iFriday printf!;被覆盖创建带标记的联合体,明确指示当前有效成员文件操作基础文件指针FILE*文件指针是语言中处理文件的核心概念,它是指向结构体的指针,包含文件当前状态信息,如C FILE文件位置指示器、缓冲区等所有文件操作函数都使用文件指针作为文件标识声明文件指针FILE*fp;打开文件函数用于打开文件并返回文件指针fopen FILE*fopenconst char*filename,constchar文件模式包括读模式,写模式(创建新文件),追加模式,读写模式,*mode;rwa r+b二进制模式(如、)例如rb wbFILE*fp=fopendata.txt,r;错误检查打开文件后应检查操作是否成功,失败返回fopen NULLFILE*fp=fopendata.txt,r;if打开文件失败文件操作失败的原因可能是权fp==NULL{perror;exitEXIT_FAILURE;}限问题、文件不存在或磁盘已满等关闭文件使用完文件后必须关闭,释放系统资源成功关闭返回,失败返回int fcloseFILE*fp;0EOF(通常是)未关闭的文件可能导致资源泄漏、数据丢失或文件损坏,尤其是在写操作后-1文件的读写文本文件操作文本文件以行为单位,包含可打印字符和控制字符文本文件操作函数包括-格式化输出输入,类似但增加文件指针参数写fprintf/fscanf/printf/scanf-fputs/fgets入读取文本行写入读取单个字符这些函数处理文本数据时会进行换行符转换/-fputc/fgetc/等特殊处理二进制文件操作二进制文件以字节为单位,直接存储内存中的数据,没有特殊字符转换二进制文件操作函数写入读取二进制数据块二进制模式适合存储结构体、图像等非文本数据,数-fwrite/fread/据读写效率更高,不会改变原始数据内容文件位置操作语言提供函数控制文件读写位置返回当前文件位置设置文件位置指针C-ftell-fseek-重置文件位置到开头这些函数允许随机访问文件内容,适用于数据库操作、文件更新rewind等场景文件操作错误处理文件操作过程中应进行错误检查检查是否达到文件末尾检查是否发生错误-feof-ferror清除错误标志打印错误信息良好的错误处理可以提高程序的稳定性和-clearerr-perror用户体验综合案例学生信息管理系统需求分析学生信息管理系统需要实现的功能包括学生信息的添加、删除、修改、查询和统计系统应存储学生的基本信息(学号、姓名、性别、年龄)和成绩信息(多门课程成绩),支持按学号查询、按姓名模糊搜索、按成绩排序等操作,并能将数据持久化存储到文件中数据结构设计使用结构体表示学生信息学号struct Student{char id
[20];//char name
[50];姓名性别(男,女)年龄//char gender;//M Fint age;//float scores
[5];//五门课程成绩平均成绩使用动态数组或链表存储多个学生记录,便float average;//};于增删改查操作功能模块实现系统分为以下主要功能模块数据管理、、
1.addStudent deleteStudent函数查询统计、、updateStudent
2.findById findByNamesortByScore函数文件操作、函数用户界面显示菜单、获取
3.saveToFile loadFromFile
4.用户输入、格式化输出结果测试与优化系统实现后需进行全面测试,包括功能测试、边界测试和异常处理测试特别关注大数据量下的性能表现、文件操作的错误处理、内存管理的合理性,以及用户体验的友好性根据测试结果进行优化,提高系统的稳定性和效率总结与学习建议高级应用掌握系统编程、网络编程、多线程等高级主题项目实践通过完整项目巩固知识,积累解决问题的经验算法与数据结构学习基本算法和数据结构,提高程序设计能力编程练习通过大量练习掌握基本语法和编程思想基础知识扎实掌握语言基本语法、数据类型和控制结构C恭喜你完成语言程序设计课程的学习!语言作为一种功能强大、应用广泛的编程语言,掌握它不仅能够帮助你开发高效的系统软件,还能为学习其他编程语言奠定坚实基础无论是底C C层系统开发、嵌入式编程还是应用软件设计,语言都具有不可替代的价值C学习编程是一个持续的过程,建议你在课程结束后继续通过实践项目巩固所学知识,关注新的编程范式和技术发展记住,编程能力的提升在于不断解决实际问题的过程中祝你在编程的道路上取得更大的进步!。
个人认证
优秀文档
获得点赞 0