还剩30页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
语言程序设计培训课件C第一部分课程导入与基础概念语言简介与发展历程C诞生背景语言特点年由在贝尔实简洁高效的语法结构1972Dennis Ritchie•验室开发,最初用于操作系统UNIX丰富的运算符和数据类型•的编写语言继承了语言的优点,C B良好的可移植性•并克服了其局限性接近硬件的底层操作能力•应用领域程序设计基础概念程序设计的基本步骤算法与流程图算法是解决问题的步骤序列,具有有穷性、确定性、可行性、输入输出等特性01问题分析流程图用图形符号描述算法流程明确需求,理解要解决的问题椭圆形表示开始结束•/矩形表示处理步骤•菱形表示判断条件02•算法设计制定解决问题的具体方案03编写代码用编程语言实现算法逻辑04调试测试验证程序正确性并优化性能语言程序结构详解C预处理指令1以#开头的命令,如#include stdio.h用于包含标准输入输出库预处理器在编译前处理这些指令,完成文件包含、宏替换等工作主函数main2程序执行的入口点,每个程序必须且只能有一个函数函数体用花括号包围,包含程序的核心逻辑代码C main{}变量声明3定义程序中使用的数据存储空间,指定变量类型和名称合理的变量命名能提高代码可读性执行语句4实现具体功能的代码行,每条语句以分号结束语句按顺序执行,可包含运算、判断、循环等操作返回语句5return0;表示程序正常结束返回值通常用于向操作系统报告程序执行状态编译、链接与执行流程源代码编译器处理.c程序员编写的原始代码文件转换为目标代码.obj链接库文件运行程序生成可执行文件.exe经典入门程序Hello,World!#include stdio.hint main{printfHello,World!\n;return0;}第二部分数据类型与运算表达式基本数据类型与变量整型浮点型字符型int float/double char用于存储整数,占用字节(位)范围约float单精度浮点数,占字节,精度约位;存储单个字符,占字节用单引号括起,如432471为亿到亿可添加修饰符short(短double双精度浮点数,占字节,精度约位A、9实际存储的是字符的码值-21+21815ASCII整型)、long(长整型)、unsigned(无符号用于存储带小数点的数值型)变量声明与初始化规则命名规则由字母、数字、下划线组成,不能以数字开头,不能使用关键字声明语法数据类型变量名;如int age;初始化声明时赋初值int age=25;多变量声明int x,y,z=10;常量与运算符常量类型算术运算符字面常量直接写在代码中的固定值,如
100、
3.
14、x加+、减-、乘*、除/、取模%符号常量用#define定义,如#define PI
3.14159,编译时替换自增++、自减--i++后增,++i先增const变量const intMAX=100;,运行时不可修改注意整数除法会舍弃小数部分关系运算符逻辑运算符等于==、不等于!=逻辑与两者都真才为真大于、小于逻辑或||一个为真即为真大于等于=、小于等于=逻辑非!取反操作结果为真或假10输入输出函数与的格式控制常用格式说明符scanf printfprintf函数用于格式化输出,将数据显示到屏幕%d-十进制整数printf格式控制串,输出列表;%f-浮点数printf年龄:%d岁\n,age;%c-字符scanf函数用于格式化输入,从键盘读取数据%s-字符串scanf格式控制串,地址列表;scanf%d,age;%lf-double类型%x-十六进制重要提示scanf中变量前必须加取地址符!与getchar putchargetchar读取单个字符,无需参数putcharch输出单个字符代码示例实现简单计算器程序#include stdio.hint main{double num1,num2,result;char operator;printf请输入第一个数字:;scanf%lf,num1;printf请输入运算符+,-,*,/:;scanf%c,operator;printf请输入第二个数字:;scanf%lf,num2;switchoperator{case+:result=num1+num2;break;case-:result=num1-num2;break;case*:result=num1*num2;break;case/:ifnum2!=0result=num1/num2;else{printf错误除数不能为0\n;return1;}break;default:printf无效的运算符\n;return1;}printf%.2f%c%.2f=%.2f\n,num1,operator,num2,result;return0;}第三部分程序流程控制选择结构语句单分支选择if-1当条件为真时执行语句块语法if条件{语句;}if score=60{语句双分支选择2if-else-printf及格\n;条件为真执行块,否则执行块if else}if age=18{printf成年人\n;多分支选择if-else if-else-3}else{依次判断多个条件,执行第一个满足条件的分支printf未成年\n;}if score=90printf优秀\n;else ifscore=75printf良好\n;嵌套语句else ifscore=60printf及格\n;4ifelse printf不及格\n;语句内部可以再包含语句,实现复杂的多重判断逻辑注意缩进以保持代码清晰if if多分支选择结构switch当需要根据一个变量的不同值执行不同操作时,switch语句比多个if-else更清晰高效每个case后要用break跳出,否则会继续执行后面的case(穿透效应)使用要点switchswitch grade{表达式必须是整型或字符型•case A:printf优秀\n;break;标签必须是常量case B:printf良好\n;break;•casecase C:printf中等\n;break;•default是可选的case D:printf及格\n;break;default:printf不及格\n;}循环结构循环循环循环for whiledo-while适用于已知循环次数的情况语法for初始化;先判断条件,条件为真才执行循环体适用于不确先执行循环体,再判断条件至少执行一次,适用条件;更新{语句;}定循环次数的场景于菜单驱动程序forint i=1;i=10;i++{int sum=0,i=1;int choice;printf%d,i;whilei=100{do{}sum+=i;printf菜单...\n;i++;scanf%d,choice;}}whilechoice!=0;先初始化,判断条件,执行循环体,然后更新计数器可能一次都不执行(条件初始为假)注意最后的分号不能省略循环控制语句语句语句break continue立即跳出当前循环,不再执行循环体剩余部分和条件判断常用于提前结跳过本次循环剩余语句,直接进入下一次循环判断用于满足某条件时跳束循环过特定处理典型案例用循环实现九九乘法表完整代码实现程序分析这个程序使用了嵌套循环的经典模式#include stdio.h外层循环()控制输出行i9int main{内层循环()每行输出的列数等于行号jint i,j;格式控制%2d使数字右对齐,保持表格整齐//外层循环控制行数换行处理内层循环结束后换行,开始下一行fori=1;i=9;i++{运行结果呈现左下三角形状,展现了到之间所有乘法组合这个例子完美展示了双重循环在实际问19//内层循环控制列数题中的应用forj=1;j=i;j++{printf%d*%d=%2d,j,i,i*j;}printf\n;//每行结束后换行}return0;}第四部分数组与字符串当需要处理大量同类型数据时,逐个定义变量既不现实也不高效数组提供了一种批量存储和管理数据的方式字符串作为字符数组的特殊应用,是程序与用户交互的重要媒介一维数组与二维数组1数组定义一维数组数据类型数组名[元素个数];二维数组数据类型数组名[行数][列数];int scores
[50];//50个整数double matrix
[3]
[4];//3行4列2数组初始化完全初始化int a
[5]={1,2,3,4,5};部分初始化int b
[5]={1,2};剩余元素自动为0省略长度int c[]={1,2,3};自动确定长度为33数组访问通过下标访问元素,下标从0开始scores
[0]=95;//第1个元素matrix
[1]
[2]=
8.5;//第2行第3列注意下标越界会导致不可预知的错误!4数组遍历使用循环处理所有元素forint i=0;i50;i++{scanf%d,scores[i];}二维数组需要嵌套循环遍历多维数组的存储特点字符数组与字符串处理字符串的存储方式常用字符串函数C语言中没有专门的字符串类型,而是用字符数组需要包含头文件#include string.h存储字符串字符串以\0(空字符,ASCII值为)作为结束标志0strlenschar name
[20]=Zhang San;返回字符串s的长度(不含\0)char greeting[]=Hello;字符串实际占用个字节Hello6H-e-l-l-o-\0strcpydest,src注意定义字符数组时,长度要比实际将字符串复制到src dest字符串长1,为\0预留空间!strcatdest,src将字符串连接到末尾src deststrcmps1,s2比较两个字符串,相等返回0使用这些函数时要注意目标字符数组必须有足够的空间,避免溢出导致程序崩溃实战演练字符串反转程序设计#include stdio.h#include string.hvoid reverseStringchar str[]{int length=strlenstr;int i,j;char temp;//使用双指针法i从头开始,j从尾开始fori=0,j=length-1;ij;i++,j--{//交换str[i]和str[j]temp=str[i];str[i]=str[j];str[j]=temp;}}int main{char text
[100];printf请输入一个字符串:;getstext;//读取整行输入printf原字符串:%s\n,text;reverseStringtext;printf反转后:%s\n,text;return0;}这个程序使用了双指针技巧一个指针从字符串开头向后移动,另一个从末尾向前移动,交换两个指针指向的字符,直到两指针相遇时间复杂度为On/2,效率很高这种算法思想在很多场景都能应用第五部分函数与模块化设计随着程序规模增大,将所有代码写在函数中会变得难以维护函数提供了代码模main块化的方式,将复杂问题分解为多个子问题分别解决合理使用函数可以提高代码复用性、可读性和可维护性函数定义与调用函数声明(原型)告诉编译器函数的存在,通常放在main函数之前返回类型函数名参数类型列表;例int addint,int;函数定义实现函数的具体功能返回类型函数名参数列表{函数体;return返回值;}函数调用在需要的地方使用函数result=add5,3;实参传递给形参,执行函数体,返回结果参数传递方式递归函数C语言采用值传递函数接收的是实参的副本,函数内修改形参不会影响实参原值函数调用自身的编程技巧必须有递归出口终止递归的条件void swapinta,int b{递归体问题的递归定义int temp=a;a=b;b=temp;int factorialint n{}//这样无法交换原变量!ifn=1return1;//出口return n*factorialn-1;}要修改实参,需要传递指针(地址传递)递归简洁优雅,但要注意栈溢出风险变量作用域与存储类别局部变量全局变量在函数或代码块内部定义,只在该范围内有效函数调用结束后,局部变量被销毁默认为在所有函数外部定义,整个程序都可以访问生命周期为整个程序运行期间过度使用会增加程auto存储类别序复杂度void func{int count=0;//全局变量int x=10;//局部变量void func{}count++;}存储类别关键字静态变量外部变量static-extern-静态局部变量在函数内定义,但生命周期延长到整个程序只初始化一次,保持上次调用的值声明一个变量是在其他文件中定义的全局变量,使得当前文件可以使用该变量//file
1.cvoid counter{int globalVar=100;static intcount=0;count++;//file
2.cprintf%d\n,count;extern intglobalVar;}printf%d\n,globalVar;静态全局变量作用域限定在定义它的文件内,其他文件无法访问用于多文件程序中共享全局变量代码示例实现阶乘的递归函数完整程序代码递归过程分析计算的递归展开过程5!#include stdio.h//递归函数声明factorial5long longfactorialint n;×=5factorial4int main{××int num;=54factorial3printf请输入一个正整数:;scanf%d,num;×××=543factorial2ifnum0{printf错误请输入正整数!\n;return1;××××=5432factorial1}long longresult=factorialnum;××××=54321printf%d!=%lld\n,num,result;=120return0;}优化建议对于大数阶乘,递归可能导致栈溢出,可改用循环实现//递归函数定义long longfactorialint n{//递归出口0!=1,1!=1ifn==0||n==1{return1;}//递归体n!=n×n-1!return n*factorialn-1;}第六部分指针与动态内存指针是语言最强大也最容易出错的特性通过指针,程序可以直接访问和操作内存地C址,实现高效的数据处理掌握指针是从初级程序员迈向高级程序员的关键一步指针基础指针变量定义指针是一个变量,它的值是另一个变量的地址int*p;//p是指向int的指针char*str;//str是指向char的指针星号*表示这是一个指针变量取地址与间接访问运算符获取变量地址*运算符访问指针指向的内容int x=10;int*p=x;//p存储x的地址*p=20;//通过p修改x的值指针与数组数组名本质上是指向第一个元素的指针常量int arr
[5]={1,2,3,4,5};int*p=arr;//p指向arr
[0]printf%d,*p+2;//输出arr
[2]指针运算p+i指向第i个元素指针与字符串字符串可以用字符数组或字符指针表示两者的区别•数组方式内容可修改charstr1[]=Hello;//字符数组char*str2=World;//字符指针•指针方式指向字符串常量,不可修改指针进阶指针数组数组的每个元素都是指针常用于存储多个字符串char*weekdays
[7]={Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};printf%s\n,weekdays
[0];//输出Monday每个元素指向一个字符串的首地址多重指针指向指针的指针,用**表示int x=10;int*p=x;//p指向xint**pp=p;//pp指向pprintf%d\n,**pp;//输出10常用于动态二维数组和参数传递函数指针指针可以指向函数,实现回调机制int addinta,int b{return a+b;}int*func_ptrint,int;//声明函数指针func_ptr=add;//指向add函数int result=func_ptr3,5;//通过指针调用函数指针在实现多态、插件系统时非常有用指针使用注意事项初始化指针、避免野指针、防止内存泄漏、不要返回局部变量地址、使用完后置为NULL实例讲解利用指针实现数组排序#include stdio.h//使用指针交换两个整数void swapint*a,int*b{int temp=*a;*a=*b;*b=temp;}//冒泡排序函数(指针版本)void bubbleSortint*arr,int n{int i,j;fori=0;in-1;i++{forj=0;jn-i-1;j++{//比较相邻元素,通过指针访问和修改if*arr+j*arr+j+1{swaparr+j,arr+j+1;}}}}//打印数组函数void printArrayint*arr,int n{forint i=0;in;i++{printf%d,*arr+i;}printf\n;}int main{int data[]={64,34,25,12,22,11,90};intn=sizeofdata/sizeofdata
[0];printf排序前:;printArraydata,n;bubbleSortdata,n;printf排序后:;printArraydata,n;return0;}这个程序展示了指针的三个典型应用传递数组地址、间接访问数组元素、通过指针修改原数据使用指针使得函数可以直接操作原数组,而不需要返回新数组,提高了效率第七部分结构体与文件操作当需要表示复杂的数据对象时,基本数据类型已经不够用了结构体允许我们将不同类型的数据组合成一个整体文件操作则让程序能够持久化保存数据,在程序关闭后数据不会丢失结构体定义与使用结构体的定义结构体成员访问使用struct关键字定义自定义数据类型使用.运算符访问成员struct Student{s
1.id=1002;int id;strcpys
1.name,王芳;char name
[50];s
1.score=
88.0;float score;printf%s:%.1f\n,s
1.name,s
1.score;};指针访问使用-运算符//声明结构体变量struct Student s1;Student*p=s1;struct Students2={1001,李明,
95.5};p-id=1003;printf%d\n,p-id;也可以使用typedef简化p-id等价于*p.idtypedef struct{int id;char name
[50];float score;}Student;Students1;//直接使用Student结构体数组1存储多个同类型对象Student class
[50];class
[0].id=1001;结构体指针2动态分配和传递结构体Student*p=s1;p-score=90;结构体作为参数3传递复杂数据到函数void printStudents{printf%s\n,s.name;}文件读写基础打开文件使用fopen函数打开文件,返回文件指针FILE*fp;fp=fopendata.txt,r;//只读模式iffp==NULL{printf文件打开失败\n;return1;}模式r读、w写、a追加、r+读写、rb二进制读读写操作字符读写fgetc、fputc字符串读写fgets、fputs格式化读写fscanf、fprintffprintffp,%d%s\n,id,name;fscanffp,%d%s,id,name;块读写fread、fwrite关闭文件使用完文件后必须关闭,释放资源fclosefp;未关闭的文件可能导致数据丢失或资源泄漏顺序读写与随机访问示例顺序写入学生信息随机访问文件FILE*fp=fopenstudents.txt,w;//移动文件指针forint i=0;i3;i++{fseekfp,0,SEEK_SET;//文件开头fprintffp,%d%s%.1f\n,fseekfp,0,SEEK_END;//文件末尾students[i].id,fseekfp,10,SEEK_CUR;//当前位置后10字节students[i].name,students[i].score;//获取当前位置}long pos=ftellfp;fclosefp;课程总结与学习资源推荐重点知识回顾推荐教材•数据类型与变量•流程控制结构•《C程序设计语言》(KR)•数组与字符串•《C PrimerPlus》•函数与递归•《C和指针》•指针与内存•《C专家编程》•结构体与文件学习建议在线资源•每天坚持编码练习•LeetCode编程练习•注重代码规范•牛客网C语言专项•多做项目实战•中国大学MOOC•参与开源社区•GitHub开源项目•学会调试技巧持续进阶的路径01打好基础熟练掌握C语言语法和标准库02算法训练学习数据结构与算法,提升编程思维03项目实战掌握语言C开启编程之门!732100+学习章节精心设计代码示例系统化的课程体系课件卡片内容实践驱动学习感谢您完成语言程序设计培训课程!编程之路刚刚开始,持续练习和实践是掌握技能的关键记住每一个伟大的程序员都是从开始的祝C HelloWorld您在编程的道路上越走越远,创造出精彩的作品!。
个人认证
优秀文档
获得点赞 0