还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
语言基础教程C欢迎参加语言基础教程学习!语言作为现代编程的基石,以其高效、灵活C C和强大的特性成为众多程序员的首选语言本课程旨在带领初学者系统掌握C语言的基本概念和编程技巧,从零基础到能够独立编写程序无论您是计算机科学专业的学生,还是对编程感兴趣的爱好者,这门课程都将为您打开编程世界的大门通过理论结合实践的学习方法,我们将一步步揭开语言的神秘面纱C课程简介语言发展史应用领域C详细了解语言从诞生到发展探索语言在操作系统开发、C C的完整历程,掌握其在编程语嵌入式系统、游戏编程、应用言发展史上的重要地位和里程软件等多个领域的广泛应用碑意义透过历史视角,理解通过具体案例,认识语言的C语言设计哲学和核心价值实际价值和市场需求C课程学习目标明确本课程的具体学习目标,包括基础语法掌握、算法设计能力、问题解决思维和实际项目开发能力等多个维度的能力培养计划为什么学习语言C与操作系统、嵌入式结合直接操作硬件资源计算机核心技能理解计算机工作原理程序员必备基础构建坚实编程思维语言是连接高级编程语言与底层硬件的桥梁,学习语言能够帮助我们深入理解计算机的工作原理它不仅是众多现代编程语言的基础,C C更是进入嵌入式开发、系统编程等领域的必经之路通过语言学习,您将获得扎实的编程思维和问题解决能力,这些能力将在您未来的编程道路上发挥不可替代的作用无论技术如何变C革,语言的核心价值始终不变C语言发展简史C年诞生于贝尔实验室1972由丹尼斯里奇()创造,最初用于开发·Dennis RitchieUNIX操作系统语言融合了高级语言的效率和低级语言的能力,创C造性地解决了系统编程的难题标准ANSI C年,美国国家标准协会()发布了语言的第一个官1989ANSI C方标准,称为或此后又有、等标准发ANSI C C89C99C11布,不断增强语言功能现代应用如今,语言广泛应用于操作系统、嵌入式系统、游戏引擎等领C域,成为计算机科学教育的基础课程,影响了众多现代编程语言的设计语言编译与平台C主流编译器跨平台特性语言程序需要通过编译器转换为机器码才能执行当前主流编语言的一大优势是跨平台性能,同一份代码经过不同平台的编C C译器包括译器编译后,可以在不同操作系统上运行这使得语言成为开C发跨平台应用的理想选择()开源免费,跨平台支•GCC GNUCompiler Collection持标准库的存在保证了跨平台代码的兼容性,但开发者需要注意C平台特定的使用可能导致的兼容性问题微软开发,集成开发环境完善API•Visual Studio基于,编译速度快,错误提示友好•Clang LLVM语言开发环境介绍C环境环境环境Windows LinuxMacOS轻量级,适合初学者命令行编译工具苹果官方•Dev-C++IDE•GCC/G++•Xcode IDE功能全面,调试工具强大的文本编辑器开发的跨平台•Visual Studio•Vim/Emacs•CLion JetBrainsIDE强大图形化集成开发环境命令行编译方式•Eclipse CDT•Terminal+GCC跨平台,配置简•Code::Blocks IDE插件轻量级但功能强大配合插件使用•VSCode+•VSCode C/C++单下的移植版•MinGW WindowsGCC本环境搭建与基本配置安装方法GCC下载或安装包•Windows MinGWCygwin使用包管理器()•Linux apt-get installgcc安装命令行工具•MacOS Xcode开发工具选择建议初学者推荐使用组合或集成度高的如VSCode+GCC IDEDev-关键是确保工具链完整,包括编辑器、编译器和调试器C++选择符合个人习惯的工具,降低学习曲线配置第一个项目创建工作目录,编写简单的程序,配置编译器路径和Hello World参数,确保能够成功编译并运行熟悉项目结构和基本操作流程,为后续学习打下基础第一个语言程序C代码示例程序结构详解Hello World头文件包含•#include#include主函数•int main函数体int main{•{}printfHello,World!\n;输出函数•printfreturn0;返回语句•return0;}每个部分都有特定的语法和功能,是语言程序的基础组成C这是每个程序员学习新语言的第一个程序它简单但包含了语C言程序的基本结构和组成部分编写与编译程序流程链接生成可执行文件编译源文件链接器将目标文件与所需的库文件链接,编写源代码使用编译器如GCC将源代码转换为目标生成最终的可执行文件这个阶段会解决使用文本编辑器创建.c文件,编写符合C文件编译过程包括预处理、编译和汇编函数调用、变量引用等外部依赖问题,生语言语法的源代码这个阶段需要注意代三个步骤编译器会检查语法错误并生成成可以直接运行的程序码风格和可读性,避免语法错误源文件中间目标文件或.o.obj是编译过程的输入语言的基本结构C函数讲解头文件语句结束符main()#include函数是程序的入语言中每个语句必须main C C口点,所有C程序必须头文件包含函数声明和以分号;结束,这是语包含一个main函数程宏定义,使用#include法规则的一部分忘记序从main函数的第一条指令导入标准库头文添加分号是初学者常见语句开始执行,一直到件使用尖括号,自定的错误之一复合语句main函数结束main义头文件使用双引号由{}括起来的多条语函数返回一个整数值,头文件的正确使用句作为一个整体,不需通常0表示程序正常结对于程序的模块化和可要在}后加分号束维护性至关重要注释的使用单行注释()多行注释()///*...*///这是一个单行注释/*这是一个int a=10;//变量初始化多行注释可以跨越多行*/单行注释以双斜杠开始,注释内容一直延续到行尾这种注//释方式简洁明了,适合简短的说明和行内注释在标准之前多行注释以开始,以结束,中间可以包含任意内容,包括换C99/**/不被支持,现在已成为主流行这种方式适合较长的说明文档、函数说明或临时禁用代码块是语言最初支持的注释方式C良好的注释习惯能够提高代码可读性和维护性注释应该解释代码的为什么而不是做了什么,因为后者通常从代码本身就能看出来避免过度注释或注释与代码不同步的情况标识符与关键字关键字列表合法标识符命名规则C语言有32个关键字,它们是语言的保•只能由字母、数字和下划线组成留字,不能作为标识符使用•不能以数字开头auto、break、case、char、const、•区分大小写continue、default、do、double、•不能是C语言的关键字else、enum、extern、float、for、goto、if、int、long、register、return、short、signed、sizeof、static、struct、switch、typedef、union、unsigned、void、volatile、while注意事项•避免使用双下划线或下划线加大写字母开头的标识符•标识符应当有意义,反映其用途•遵循一致的命名风格变量与常量变量声明初始化/数据的临时存储空间常量定义不可修改的固定值命名习惯清晰反映数据含义变量是程序中可以改变值的存储单元,而常量是固定不变的值语言中,变量声明指定了变量的类型和名称,如变量初始化C int count;则是在声明的同时赋予初值,如intcount=0;常量有两种定义方式使用关键字()或通过预处理器宏定义()良好的命名习惯是使const constint MAX=100;#define MAX100用小写字母为变量命名,全大写字母为常量命名,多个单词用下划线连接或使用驼峰命名法数据类型概述变量内存分布每个变量在内存中占据特定大小的空间,如通常占字节,占字节了解内存分int4char1基本数据类型布有助于优化程序性能和解决内存相关问类型转换题语言提供了多种基本数据类型,包括整型不同类型数据之间可以进行转换,分为隐式C、浮点型、转换自动进行和显式转换通过强制类型转int,short,long float,double字符型等每种类型有特定的内存占换操作符类型转换需要注意可能的精度损char用和表示范围失和溢出问题整型与实型数据类型字节数取值范围应用场景节省内存的小整数short2-32768~32767常用整数类型int4-2^31~2^31-1long4或8取决于系统大整数处理float46~7位有效数字一般精度浮点计算double815~16位有效数字高精度浮点计算整型变量用于存储整数,C语言提供不同大小的整型以适应不同的需求实型(浮点型)变量用于存储带小数点的数值,float提供单精度浮点数,而double提供双精度浮点数在需要精确计算的场景下,需要注意浮点数的精度问题字符型和枚举类型类型及处理码表枚举类型char ASCII类型在语言中用于存储单个字(美国信息交换标准代码)是计算char CASCIIenum Week{Mon,Tue,Wed,Thu,符,实际上是一个小整数,通常占用个机中最常用的字符编码系统,定义了1128Fri,Sat,Sun};字节字符常量用单引号括起来,如个字符的编码常见的码包括ASCIIenum Weektoday=Wed;字符变量可以进行算术运算,因为A//Wed的值为2(默认从0开始计数)它们实际上是码值ASCII数字•0-948-57大写字母•A-Z65-90char grade=A;小写字母printf%c的ASCII码是%d\n,•a-z97-122枚举类型用于定义一组具有离散值的常grade,grade;量,提高了代码的可读性和可维护性//输出A的ASCII码是65语言标准输入输出C格式化输出基本用法printf scanfprintf整数:%d\n浮点数:%f\n字符:%c\n,int age;10,
3.14,A;float height;scanf%d%f,age,height;函数用于格式化输出,第一个参数是格式化字符串,包含普printf通文本和格式说明符常用的格式说明符有函数用于从标准输入读取数据,格式说明符类似注scanf printf意要传递变量的地址(使用运算符)而不是变量本身当读取字十进制整数•%d-符串时,不需要使用运算符浮点数•%f-字符•%c-字符串•%s-输入输出是程序与用户交互的基础合理使用格式说明符可以提高输出的可读性和美观性在处理用户输入时,一定要进行有效性检查,防止非法输入导致程序崩溃转义字符使用常见转义字符在字符串中的应用转义字符以反斜杠开头,用于转义字符在字符串常量中经常\表示特殊字符或控制字符常使用,用于格式化输出或表示见的转义字符包括(换无法直接键入的字符例如,\n行)、(制表符)、(回使用来分行显示文本,使用\t\r\n车)、(退格)、(单引来对齐输出内容,使用在字\b\\t\号)、(双引号)、(反斜符串中插入双引号\\\杠)等格式化输出案例通过组合使用转义字符,可以创建格式化良好的输出例如,制作表格输出时使用对齐列,使用分隔行;显示路径时使用表示反斜杠;显示\t\n\\引用文本时使用包围文本内容\熟练掌握转义字符的使用,可以使程序输出更加美观和专业在调试和用户交互中,合理的输出格式能够大大提高程序的可用性和用户体验运算符初识语言中的运算符是执行特定操作的符号算术运算符(、、、、)用于执行基本的数学运算,其中是取余运算,只适用于C+-*/%%整数赋值运算符()用于将值赋给变量,还有复合赋值运算符(、、、、)用于简化赋值和运算的组合=+=-=*=/=%=关系运算符(、、、、、)用于比较两个值,返回结果为真()或假()在语言中,任何非零值被视为真,而====!=10C0被视为假使用这些运算符时,要注意运算优先级和结合律,必要时使用括号明确表达式的计算顺序逻辑与位运算符逻辑运算符位运算符逻辑与()两边都为真时结按位与()对应位都为则结••1果为真果为1逻辑或()至少一边为真时按位或()对应位有一个为•||•|1结果为真则结果为1逻辑非()真变假,假变真按位异或()对应位不同则结•!•^果为1用于组合多个条件表达式,常用于if按位取反()变,变语句和循环控制•~0110移位运算符左移()位向左移动,右侧补•0右移()位向右移动,左侧补符号位或•0左移位相当于乘以,右移位相当于除以(整数部分)n2^n n2^n运算符优先级与结合性优先级运算符结合性1(最高)、[]、-、.从左到右2!、~、++、--、+、-(单从右到左目)、*(指针)、(地址)3*、/、%从左到右4+、-(双目)从左到右
5、从左到右
6、=、、=从左到右7==、!=从左到右8-
13、^、|、、||、:、=及不同方向复合赋值运算符优先级决定了表达式中运算的执行顺序优先级高的运算符先执行,优先级相同时按照结合性确定执行顺序结合性有从左到右和从右到左两种使用括号可以改变运算的优先级,使表达式按照预期顺序执行表达式与类型转换强制类型转换通过强制类型转换运算符,程序员可以明确指定转换的目标类型语法为类型名表达隐式类型转换式例如,int
3.14将浮点数
3.14转换为整数3强制类型转换可能导致数据精度丢失或溢转换注意事项当不同类型的数据进行运算时,编译器会自C出动进行类型转换,将较小类型提升为较大类类型转换需要谨慎处理,特别是从高精度向低型这种转换遵循特定规则,一般是向精度更精度转换时可能造成数据丢失在进行除法运高的类型转换,例如整数与浮点数运算时,整算时尤其要注意,整数除法会截断小数部分,数会被转换为浮点数例如的结果是而不是5/
222.51顺序结构程序设计语句执行顺序顺序结构是最基本的程序结构,程序按照语句的先后顺序一条一条地执行每条语句执行完后,控制自动转移到下一条语句这是程序执行的默认流程方式代码实际流程演示在一个简单的顺序结构程序中,从函数开始,依次执行声明变main量、赋值、计算、输出等操作程序流程是线性的,没有跳转或重复执行的部分,执行路径是确定的常见逻辑陷阱虽然顺序结构看似简单,但仍有常见问题需要注意语句执行顺序错误导致的计算结果不正确、变量使用前未初始化、计算中的溢出或精度问题等这些问题可能不会产生编译错误,但会导致程序运行结果不正确分支结构语句if语句基本格式语句if if-else最简单的语句由关键字、条件表达式语句提供了两个分支当条件为if if if-else和执行语句组成当条件表达式结果为1真时执行后的语句,否则执行后if else真(非零值)时,执行相应的语句;否的语句,从而确保两个分支中有一个会则跳过这些语句被执行多分支结构if-else if嵌套语句if通过结构可以实现多分if-else if-else语句可以嵌套使用,即在一个语句的ifif支选择,程序会从上到下检查条件,执3执行部分再包含另一个语句,用于处if行第一个条件为真的分支,然后跳出整理多条件判断的复杂情况个结构多分支选择switch语法结构和break default语句用于跳出结构,如果没有,程序会继续执行下break switchbreakswitch表达式{一个中的语句,这称为落空或穿透子句是可选的,casedefaultcase常量1:用于处理所有都不匹配的情况case语句块1;break;适用场景case常量2:语句适用于根据一个变量的不同值执行不同代码的情况,特别语句块2;switch是当这个变量有多个离散值时相比于多个语句,语if-else ifswitchbreak;句通常更清晰、效率更高default:默认语句块;}语句根据表达式的值选择执行路径表达式的结果必须是整型switch(、等)每个后面跟一个常量值和冒号,当表达式的值char intcase等于这个常量时,执行对应的语句块循环结构语句for循环基本格式forfor初始化;条件表达式;更新表达式{循环体语句;}for循环首先执行初始化语句,然后检查条件表达式如果条件为真,执行循环体和更新表达式,然后重新检查条件这个过程重复进行,直到条件为假循环执行流程forfor循环的执行流程1执行初始化表达式,通常用于初始化计数器;2判断条件表达式,如果为假则退出循环;3执行循环体;4执行更新表达式,通常用于更新计数器;5返回第2步继续执行嵌套循环forfor循环可以嵌套使用,即在一个循环体内包含另一个循环嵌套循环常用于处理多维数组、生成特定模式等任务内层循环的每次完整执行只相当于外层循环的一次迭代与循环while do-while循环循环while do-whilewhile条件表达式{do{循环体语句;循环体语句;}}while条件表达式;循环首先检查条件表达式,如果为真则执行循环体,然后循环先执行循环体,然后检查条件表达式如果条件while do-while再次检查条件这个过程重复进行,直到条件为假如果初始条为真,则重复执行循环体和条件检查由于条件检查在循环体之件就为假,循环体一次也不会执行后,循环至少会执行一次循环体do-while循环适用于不确定循环次数,需要根据条件判断是否继续循环适用于需要至少执行一次循环体的情况,例如至while do-while循环的情况,例如读取用户输入直到特定值出现少要进行一次有效性检查的用户输入处理跳转语句语句语句语句break continuegoto语句用于语句用于语句可以无条件跳转到程序中标记的break continuegoto位置(标签),语法为标签名和goto;立即终止当前循环,跳出循环结构跳过当前循环的剩余语句••标签名语句:;•在switch语句中结束case处理•直接进入下一次循环迭代尽管语句功能强大,但它可能导致程goto只能跳出最内层的循环,对于嵌套循在循环中,会跳到更新表达break forcontinue序流程混乱,难以理解和维护,一般推荐环,它不能直接跳出外层循环式;在循环中,跳到条件while/do-while使用其他控制结构替代判断综合练习流程结构1猜数字游戏使用随机数生成器产生1-100之间的数字,用户输入猜测值,程序告知是大了还是小了,直到猜对为止统计猜测次数2打印乘法表使用嵌套for循环打印九九乘法表要求格式整齐,对齐方式合理3判断素数接受用户输入的一个整数,判断它是否为素数一个数如果只能被1和自身整除,则为素数4寻找完数编写程序找出1000以内的完数完数是指一个数等于它的所有因子(不包括自身)之和,如6=1+2+3数组初步一维数组定义数组初始化与访问数组元素可以在声明时一次性初始化,也可以在程序执行过程中一个//声明并初始化一个数组一个地赋值访问数组元素通过下标操作符进行,例如[]scores
[2]int scores
[5]={85,92,78,90,88};表示数组中下标为的元素(第三个元素)scores2//声明一个数组,稍后初始化数组遍历与操作int numbers
[10];数组处理通常通过循环来完成最常见的操作包括遍历数组、查找特定元素、计算统计值(如总和、平均值、最大值、最小值)等数组//省略数组大小(根据初始化元素确定)作为函数参数时,传递的是数组的起始地址,而不是数组的完整副int days[]={31,28,31,30,31,30,本31,31,30,31,30,31};数组是同一类型的多个元素的集合,数组名表示第一个元素的地址在语言中,数组下标从开始,最后一个元素的下标是数组大小减C01多维数组二维数组定义表格形式的数据结构内存存储方式行优先顺序连续存储常见矩阵操作转置、相加、乘法等二维数组可以看作是数组的数组,通常用于表示矩阵或表格数据声明二维数组的语法是类型名数组名行数列数例如,[][]int matrix
[3]
[4]声明了一个行列的整型二维数组二维数组可以通过嵌套花括号进行初始化,如34int matrix
[2]
[3]={{1,2,3},{4,5,6}};在内存中,二维数组按行优先顺序连续存储访问二维数组元素需要两个下标第一个指定行,第二个指定列,如表示第行第列的matrix
[1]
[2]23元素处理二维数组通常使用嵌套循环,外层循环遍历行,内层循环遍历列字符串及字符串操作字符串定义与表示字符串输入输出字符串库函数语言中,字符串是以空字符字符串输入可以使用标准库提供了丰富的字符串处理C scanf%s,C()结尾的字符数组字符串,但它会在遇到空白字符时停函数,包括(计算长\0str strlen可以用字符数组或字符指针表示止读取更安全的方法是使用度)、(复制)、strcpy字符串常量用双引号括起来,如,它可以读(连接)、(比fgetsstr,size,stdin strcatstrcmp定义字符串时需要确保取包含空格的整行输入输出字符较)、(查找)Hello strchr/strstr数组大小足够容纳所有字符和结束串可以使用或等使用这些函数需要包含printf%s,str符函数头文件putsstr string.h语言标准库介绍Cstdio.h stdlib.h string.h标准输入输出库,提供文件操作和控制台标准工具库,提供内存管理、随机数、字字符串处理库,提供字符串操作和内存操输入输出功能符串转换等功能作函数格式化输入输出动态内存分配释放字符串复制•printf/scanf-•malloc/free-/•strcpy/strncpy-文件打开关闭随机数生成字符串连接•fopen/fclose-•rand/srand-•strcat/strncat-文件读写字符串转换为数值字符串比较•fread/fwrite-•atoi/atof-•strcmp-字符串格式化终止程序执行内存块复制•sprintf/sscanf-•exit-•memcpy/memmove-函数基础函数定义函数定义包括返回类型、函数名、参数列表和函数体函数体是由花括号括起来的一组语句,执行特定的任务并可能返回一个值函数声明函数声明告诉编译器函数的名称、返回类型和参数列表,但不包含函数体声明通常放在调用该函数的代码之前,如果函数定义在调用之后或在另一个文件中函数调用函数调用通过函数名和参数列表来执行函数当函数被调用时,程序流程转到该函数,执行函数体中的语句,然后返回到调用点继续执行语言中的函数是组织代码的基本单位函数使程序模块化,提高了代码的可读性、可维C护性和重用性函数可以有参数(输入)和返回值(输出),也可以没有参数或没有返回值(用表示)函数参数可以按值传递(传递参数的副本)或按地址传递(传递参数void的地址)变量作用域与生命周期全局变量全局变量在所有函数外部声明,对整个程序可见它们在程序启动时创建,程序结束时销毁全局变量存储在数据段局部变量中,默认初始化为全局变量应谨慎0局部变量在函数或代码块内部声明,只使用,因为它们可能导致代码耦合和难在该函数或代码块内可见它们在函数以维护调用时创建,函数返回时销毁局部变1量存储在栈上,除非使用static关键静态变量字每次调用函数时,局部变量都会重静态变量使用关键字声明静态static新初始化,除非是静态局部变量局部变量在函数内部声明,但在函数调用之间保持其值静态全局变量仅在声明它的文件内可见,无法从其他文件访问静态变量存储在数据段中,初始化为(如果没有显式初始化)0头文件和多文件程序原理#include预处理器文本替换机制1头文件自定义函数声明与宏定义集合多文件项目组织模块化代码结构指令是预处理器的一部分,它在编译前将指定文件的内容复制到当前文件中使用尖括号包含系统头文件,使用双引号包含用#include C户自定义头文件预处理器会首先在当前目录查找双引号包含的文件,然后在系统目录查找自定义头文件通常包含函数声明、宏定义、结构定义等,以便在多个源文件之间共享为防止头文件被重复包含,应使用条件编译指令如、和创建头文件防护大型项目通常分为多个文件和相应的文件,提高了代码的可读性、可维护性和编译效率#ifndef#define#endif.c.h指针初步指针概念指针操作指针是一种特殊的变量,用于存储另一个变量的内存地址指针int x=10;使语言能够直接访问和操作内存,这是语言强大功能的重要C Cint*p=x;//取地址,p指向x基础指针类型表示它指向的数据类型,如表示是一个int*p p指向整数的指针printfx的值%d\n,x;//10指针的大小取决于系统架构,通常在32位系统上是4字节,在printfx的地址%p\n,x;//地址值64位系统上是8字节,不论它指向的数据类型是什么NULL指printfp的值%p\n,p;//与x相同针(值为0)表示指针不指向任何有效的内存地址printfp指向的值%d\n,*p;//10*p=20;//通过指针修改x的值printf修改后x的值%d\n,x;//20指针与数组12数组名与指针指针访问数组元素在大多数上下文中,数组名可视为指向数组指针可以通过算术运算访问数组元素若p指第一个元素的常量指针即如果有数组int向数组首元素,则p+i指向第i+1个元素,arr
[5],则arr等价于arr
[0],都表示数组第*p+i等价于arr[i]指针访问数组通常在需一个元素的地址要动态处理数组或函数间传递数组时使用3数组与指针的区别尽管相似,数组和指针有本质区别数组是一段连续内存的标识符,不能被赋新值;指针是变量,可以指向不同地址数组名的sizeof返回整个数组的大小,而指针的sizeof返回指针本身的大小字符串与指针字符串常量与指针指针操作字符串char*str=Hello;//str指向字符串常量char s[]=programming;char arr[]=Hello;//字符数组包含副本char*p=s;//遍历并打印每个字符字符串常量存储在内存的只读区域,因此通过指针不应修改其内容字符数组则创while*p!=\0{建了字符串的可修改副本字符串指针适合处理只读字符串,节省内存;字符数组printf%c,*p;适合需要修改内容的情况p++;//移动到下一个字符}//重置指针p=s;//修改第一个字符*p=P;printf\n%s\n,s;//Programming指针操作字符串时需要注意字符串必须以空字符\0结尾;越界访问可能导致未定义行为;修改字符串常量是不允许的,会导致运行时错误字符串处理函数如strcpy、strcmp内部都使用指针实现字符串操作,理解指针对于高效处理字符串至关重要指针与函数指针作为函数参数值传递与地址传递指针实现函数swapC语言函数参数默认为值传递,即函数接收参数值的//通过指针修改变量值副本使用指针可以实现地址传递,使函数能够访问void swapint*a,int*b{void changeint*p{和修改调用者的变量大型数据结构使用指针传递可int temp=*a;*p=20;//修改指针指向的值以提高效率,避免数据复制*a=*b;}*b=temp;}int x=10;changex;//传递x的地址int x=5,y=10;printf%d\n,x;//输出20swapx,y;printfx=%d,y=%d\n,x,y;//x=10,y=5指针参数使函数能够修改调用者提供的变量值,实现按引用传递的效果动态内存分配动态内存分配函数•mallocsize分配指定字节的内存,不初始化•callocn,size分配n个size字节的内存,初始化为0•reallocptr,size调整之前分配的内存大小•freeptr释放之前分配的内存这些函数都位于stdlib.h头文件中内存泄漏与防护内存泄漏发生在分配了内存但未释放的情况下长期运行的程序中,内存泄漏会导致内存耗尽防护措施包括跟踪所有分配的内存;确保每个malloc都有对应的free;分配失败时进行错误处理;使用内存调试工具动态数组实现//动态分配整数数组int*arr=int*malloc5*sizeofint;if arr==NULL{//内存分配失败处理exit1;}//使用数组for int i=0;i5;i++{arr[i]=i*10;}//使用完毕后释放内存freearr;arr=NULL;//避免悬空指针结构体()定义struct结构体定义与声明结构体成员访问使用点运算符(.)访问结构体成员//定义结构体类型struct Student{strcpys
1.name,李四;char name
[50];s
1.age=22;int age;s
1.gpa=
3.67;float gpa;};printf姓名%s\n,s
1.name;printf年龄%d\n,s
1.age;//声明结构体变量printfGPA%.2f\n,s
1.gpa;struct Student s1;struct Students2={张三,20,
3.85};结构体数组//使用typedef简化声明typedef struct{char title
[100];struct Studentclass
[40];//40个学生char author
[50];int year;//初始化和访问}Book;strcpyclass
[0].name,王五;class
[0].age=19;Book b1={C程序设计,谭浩强,2010};结构体与指针结构体指针声明与初始化箭头运算符与点运算符struct Student{//使用点运算符(变量)char name
[50];printf姓名%s\n,s.name;int age;float gpa;//使用箭头运算符(指针)};printf姓名%s\n,ps-name;//等价于*ps.namestruct Students={张三,20,
3.85};struct Student*ps=s;//动态分配的结构体strcpynew_student-name,李四;//动态分配结构体new_student-age=22;struct Student*new_student=new_student-gpa=
3.67;struct Student*mallocsizeofstructStudent;结构体作为函数参数//按值传递(复制整个结构体)void printStudentstruct Students{printf%s,%d,%.2f\n,s.name,s.age,s.gpa;}//按地址传递(只传递指针)void updateAgestruct Student*ps,int new_age{ps-age=new_age;}联合体()与枚举union联合体()枚举()union enum//定义联合体//定义枚举类型union Data{enum Weekday{inti;Monday,//0float f;Tuesday,//1char str
[20];Wednesday,//2};Thursday,//3Friday,//4//声明联合体变量Saturday,//5union Datadata;Sunday//6};//使用联合体data.i=10;//自定义枚举值printfdata.i:%d\n,data.i;enum Month{Jan=1,Feb,Mar,Apr,May,Jun,data.f=
220.5;Jul,Aug,Sep,Oct,Nov,Decprintfdata.f:%f\n,data.f;};//此时data.i的值已不再有效//使用枚举strcpydata.str,C语言;enum Weekdaytoday=Wednesday;printfdata.str:%s\n,data.str;if today==Wednesday{//此时data.f的值已不再有效printf今天是周三\n;}联合体的所有成员共享同一块内存空间,任何时候只有一个成员是有效的联合体的大小等于其最大成员的大小枚举为整型常量提供了有意义的名称,提高了代码的可读性枚举常量默认从0开始递增,也可以显式指定值文件操作文件指针与打开关闭文件/FILE*fp;//打开文件(以写入模式)fp=fopentest.txt,w;if fp==NULL{printf无法打开文件!\n;return1;}//使用文件...//关闭文件fclosefp;常用的文件模式r(读)、w(写,覆盖)、a(追加)、r+(读写)、w+(读写,覆盖)、a+(读写,追加)文本文件读写//写入文本文件fprintffp,Hello,%s!\n,world;fputsWelcome toC programming.\n,fp;//读取文本文件char buffer
[100];fp=fopentest.txt,r;while fgetsbuffer,100,fp!=NULL{printf%s,buffer;}二进制文件读写struct Person{char name
[50];int age;};struct Personperson={张三,25};//写入二进制文件fp=fopendata.bin,wb;fwriteperson,sizeofstruct Person,1,fp;//读取二进制文件fp=fopendata.bin,rb;freadperson,sizeofstruct Person,1,fp;错误处理与调试常见错误类型调试参数基本用法GCC gdb•语法错误编译器能够检测,如缺少分•-Wall启用所有警告•启动gdb[program]号、括号不匹配•-Werror将所有警告视为错误•设置断点break[行号/函数名]•链接错误找不到函数定义、多重定义等•-g生成调试信息•运行程序run[参数]•运行时错误导致程序崩溃,如除零、内•-O0禁用优化,方便调试•单步执行next(不进入函数)、step存访问越界(进入函数)编译命令示例gcc-Wall-g-O0-o•逻辑错误程序运行但结果不正确,最难•继续执行continueprogram program.c调试•查看变量print[变量名]•查看调用栈backtrace语言常见陷阱C指针误用未初始化指针、使用已释放的内存、内存泄漏是常见指针问题使用指针前必须确保其指向有效内存避免悬空指针(dangling pointer)和野指针(wildpointer)使用free后应将指针设为NULL未初始化变量C语言不会自动初始化局部变量,使用未初始化的变量会导致不可预测的行为养成始终初始化变量的好习惯,即使是临时变量也不例外编译器警告可以帮助发现此类问题数组越界与内存泄漏C语言不检查数组边界,越界访问可能导致覆盖其他数据或程序崩溃确保循环控制变量不超出数组范围,尤其是以0为起始索引时动态分配的内存必须正确释放,否则会导致内存泄漏综合案例实战学生信息管理系统关键代码结构这个案例展示了一个简单的学生信息管理系统,涵盖了C语言的基本语法、结构体、文//学生结构体定义件操作和动态内存管理等多个知识点系统具有添加、查询、修改、删除和统计学生struct Student{信息的功能char name
[50];系统功能char id
[20];float score;•添加学生信息(姓名、学号、成绩)struct Student*next;•按学号查询学生};•修改学生信息//函数声明•删除学生信息void addStudentstructStudent**head;•显示所有学生信息structStudent*findStudentstruct Student*head,•计算平均成绩和找出最高分char*id;void deleteStudentstructStudent**head,char*id;void saveToFilestructStudent*head;structStudent*loadFromFile;系统采用链表结构存储学生信息,支持动态增删改查数据持久化通过文件操作实现,程序启动时从文件加载数据,修改后保存回文件拓展与学习建议掌握语言基础后,可以向多个方向拓展学习数据结构与算法是计算机科学的核心,语言是学习它们的理想工具;嵌入式开发利用语CCC言直接操作硬件的能力,应用于各种智能设备;系统编程包括操作系统开发、驱动程序和高性能应用,语言在这些领域具有明显优势C推荐学习资源《程序设计语言》()是语言的经典著作;《和指针》深入讲解指针概念;《数据结构与算法分析语言描C KRCCC述》结合理论和实践;《系统编程手册》详细介绍系统编程实践是提高的关键,建议从简单项目开始,逐步挑战更复杂的问Linux/UNIX题课程总结与答疑程序结构基础概念熟练运用顺序、分支、循环三种基本结构2掌握语言的数据类型、运算符和表达式C数组与指针深入理解数组、指针及它们的关系结构体与文件函数与模块化能够处理复杂数据结构和持久化存储能够设计和实现模块化程序通过本课程的学习,您已经掌握了语言的核心概念和编程技巧从基本语法到复杂数据结构,从简单的控制流到文件操作和内存管理,这些知识构C成了坚实的编程基础语言的学习不仅是掌握一门编程语言,更是建立计算思维和问题解决能力的过程C继续学习的建议保持编码习惯,每天练习;参与开源项目,学习他人代码;阅读经典书籍,深化理解;尝试实际项目,应用所学知识最重要的是,编程是一项实践技能,只有通过不断的实践和解决实际问题,才能真正掌握这门艺术。
个人认证
优秀文档
获得点赞 0