您好,欢迎访问三七文档
C语言重要资料范浩1函数一。函数基本概念函数其实就是一段代码这段代码一般逻辑上具有一定的联系:用来实现一个特定的功能这段代码我们一般会封装起来,并给它取一个名字,这就构成了一个函数函数最终是为了“重用”函数其实是C语言模块化的体现,比如:程序要接收用户从键盘输入的两个整数m和n,然后求1+2+3+…+m1+2+3+…+n这两个步骤的运算方法是相同的,只有参数不同,如果不定义函数,我们需要在主函数中把两段几乎相同的代码写两遍代码:#includestdio.hmain(){intm,n;intk,sum1=0,sum2=0;scanf(%d,%d,&m,&n);for(k=1;k=m;k++){sum1+=k;}for(k=1;k=n;k++){sum2+=k;}printf(%d,%d\n,sum1,sum2);}这段代码的核心代码是两个for循环,这两个for循环结构完全相同,只是参数不同,运算结果不同,而在这里我们就要把这段几乎相同的代码写两遍这里就提出了“函数”,函数就是把一些实现一定功能的代码封装起来,一次封装,可以多次调用——重用二。函数的定义把实现一定功能的代码封装起来1).要能描述代码结构C语言重要资料范浩22).接收外面给它的参数3).把运算结果返回4).要给封装起一个名字1.函数定义的格式:返回值类型函数名(形式参数列表){函数体}标红色的部分叫:函数头返回值类型:描述函数要返回的运算结果的数据类型如果函数不需要返回值,返回值类型描述可以用void,也可以直接省略如果函数有返回值,函数体中就要用return语句,return语句后面要有返回的实际数据(return**;)Return语句后面返回的实际数据的类型要与描述类型兼容(实际返回的数据可以直接转换成返回值类型描述的类型)如果函数没有返回值,return语句后面可以什么都不加,直接return;,或者连return语句直接省略函数名:符合标识符的命名规则形式参数列表:形式参数是用来说明函数的参数的形式:参数的类型,参数的个数格式:参数1的类型参数1的名称,参数2的类型参数2的名称,…如果函数不需要形式参数,可以用void,也可以直接省略三。函数调用1.格式:函数名(实际参数)函数名:就是要调用的封装起来的代码所起的名字实际参数:要传递给函数的实际的数据可以是变量、常量、表达式、可以是一个函数的调用实参的个数要和形参的个数一致类型要兼容(后面解释)2.调用方式1)直接作为语句调用,(一般用来调用么有返回值的函数)2)把函数放入表达式3)把函数作为另外要给函数的实际参数函数的定义要放在被调用之前,否则要声明四。函数声明样式同函数头,后面直接加分号作用:告诉编译器,程序中有这么一个函数的定义,但是不在这里案例:#includestdio.h/*C语言重要资料范浩3函数声明*/Print();/*函数定义*/intAdd(inta,intb){returna+b;}/*定义函数,求1+2+...+某个整数某个整数:是需要外界给定的,这就是参数形式:1个参数,int类型返回结果:运算结果什么类型:int*/intSum(intn){intk;int*p=&k;/*定义验证返回值*/intsum=0;for(k=1;k=n;k++){sum+=k;}/*如果返回的是char,会直接返回,因为可以直接进行类型转换如果返回的是一个浮点数,会提示有数据丢失,也可以返回,因为类型兼容*/returnsum;/*会报错返回的是一个指针int*,无法直接转换成int*///returnp;}voidmain(void){intm,n;intk,sum1=0,sum2=0,sum3;scanf(%d,%d,&m,&n);/*调用函数:调用形式:表达式C语言重要资料范浩4把函数的运算结果(返回值)按照表达式完成运算,再赋值给变量*/sum1=Sum(m);sum2=Sum(n);sum3=2*Sum(n);printf(%d,%d,%d,%d\n,sum1,sum2,sum3,Add(Sum(m),sum2));/*调用无返回值的方法,直接作为一个语句,后面要加上;*/Print();}/*定义无参数的函数*/Print(){printf(abcd-----------);//return;}练习:课后练习8#includestdio.h/*如果题目规定在主函数中显示转换的结果我们需要把字符数组返回但是,函数一般不会把在函数内定义的数组以指针的形式返回函数一般不返回指针或者数组*/voidPrintStr(intk){chars[10];s[0]=k/1000+0x30;s[1]='';s[2]=k%1000/100+0x30;s[3]='';s[4]=k%100/10+0x30;s[5]='';s[6]=k%10+0x30;s[7]='\0';/*--s[7]=0,'\0'的值就是0*/printf(%s\n,s);}voidmain(void)C语言重要资料范浩5{intk;char*p;scanf(%d,&k);PrintStr(k);}五。函数调用过程中的参数传递实参传递给形参函数定义:Intfun1(inta,intb,intc)调用的时候:fun1(a1,b1,c1);实参是按照顺序,逐个传递给形参的A1的值传递给了a:a1实参要能直接转换成形参a的类型,或者可以兼容B1的值传递给了b:b1的类型要能转换成形参b的类型,或者可以兼容C1的值传递给了c:。。。六。函数的调用过程函数的调用过程其实是代码的跳转C语言重要资料范浩6当代码中调用一个函数的时候,就是跳转(步骤2,5)到这个函数的第一条语句开始执行,当函数执行完毕(碰到了return语句,执行到函数的最后一条语句(即使没有return))函数会返回(步骤4,7)调用主调函数,继续执行函数的内部定义的变量和函数的形参变量,都是在函数被调用的时候分配存储空间。七、变量的作用域案例:#includestdio.h/*定义全局变量变量不属于任何函数全局变量位于程序的全局区域程序的全局区,是任何函数都可以访问的全局变量的声明周期:从程序开始运行开始,到程序运行结束终止*/intm=10,n=20;/*函数内定义的变量是局部变量函数的形参是作为局部变量C语言重要资料范浩7形参的名称可以与实参变量相同,但是不能与函数局部变量名称相同局部变量的生命周期:从函数被调用开始,到函数执行结束终止*/intSum(intnum){intk;intsum=0;for(k=0;k=num;k++){sum+=k;}/*打印的全局变量*/printf(Sum:%d,%d\n,m,n);returnsum;}intMul(intnum){intk;intmul=1;for(k=1;k=num;k++){mul*=k;}returnmul;}main(){/*局部变量与全局变量重名,局部变量在函数内会覆盖全局变量*/intnum,m,n;scanf(%d,&num);m=Sum(num);n=Mul(num);/*这里输出的是main的局部变量m和n的值,也就是求阶乘和连续加的值,而不是全局变量的值*/printf(main:%d,%d\n,m,n);}1.主函数运行到调用Sum之前C语言重要资料范浩8蓝色的区域为Main函数的空间2.调用Sum期间存储分配蓝色的区域是main的存储空间,绿色的区域是Sum的存储空间,他们彼此是不能互相访问的,因此变量即使重名,也没有关系,不冲突主函数中有两个变量与全局变量重名了,在函数内部定义的变量(局部变量)与C语言重要资料范浩9全局变量重名时,会覆盖全局变量3.调用Sum结束,返回主函数时,存储空间变为:调用Sum之前的存储空间,Sum所占的绿色的区域被释放了4.调用Mul期间的存储橙色的空间实Mul的存储空间,其实覆盖了刚才Sum的存储空间,这时main的存储空间不变5.Mul执行结束,回到6.主函数执行结束C语言重要资料范浩10整个存储空间,包括代码区、常量区、全局区、栈、堆,都被释放掉。八、函数的参数传递参数的传递其实是把实参的值复制到形式参数(变量)的空间里实参传递给形参,函数的返回值的传递函数能否返回多个值?不行1.执行完scanf后,用户输入了5;main函数空间内的变量num里面存储了5;2.调用Sum函数时,为sum分配存储空间,图中紫色的部分,这时,会把主函数的num的值复制到sum函数的num变量空间中3.Sum函数执行完毕,还没返回的时候C语言重要资料范浩114.Sum返回,因为Sum里面有returnsum语句所以程序会在一个临时的存储空间里面存储sum的值(绿色的区域),然后释放Sum的存储空间,根据主函数的语句,把临时空间里面的值赋值给变量m。九、指针做函数参数案例:#includestdio.h/*指针做函数参数*/voidfun1(int*p,intlength){intk;for(k=0;klength;k++){*p=(*p)*2;p++;/*下面的代码也是可行的*///p[k]=p[k]*2;}}C语言重要资料范浩12/*用数组做函数形参,也需要传送一个地址过来但是其实这里的a也是一个变量,也可以做运算,*/voidfun2(inta[],intlength){intk;for(k=0;klength;k++){a[k]=a[k]*2;/*下面的代码也是可行的*///*a=(*a)*2;//a++;}}main(){inta[5]={1,2,3,4,5};intk;for(k=0;k5;k++){printf(%d,,a[k]);}printf(\n);fun1(a,5);for(k=0;k5;k++){printf(%d,,a[k]);}printf(\n);fun2(&a[0],5);for(k=0;k5;k++){printf(%d,,a[k]);}printf(\n);}C语言重要资料范浩13十。返回值为指针的函数:案例:/*函数返回值为指针的时候,不要试图用指针返回一个局部变量的值函数一旦执行完毕,局部变量都释放了即使返回了地址,也已经无法访问这块存储区域*/int*fun1(intk){intb[5]={8,4,6,8,10};intm;for(m=0;m5;m++){b[m]=b[m]+k;}returnb;}main(){int*p;intk;p=fun1(2);/*调用函数之后打印结果,*/for(k=0;k5;k++)C语言重要资料范浩14{printf(%d,,*p++);}}练习:统计字符串长度和统计字符串中字母和数字的个数#includestdio.hintnumC=0,numN=0;/*定义一个函数,统计字符串的长度*/intstrLen(char*ch){intlength=0;while(*ch!='\0'){length++;ch++;}returnlength;}/*统计字符串中字母和数组的个数函数要给出两个结果:字母的个数、数字的个数因此不能用函数的返回值给出把主函数的变量以地址的形式传递给函数在函数中改变变量的值*/voidstrNandC(char*ch,int*n1,int*n2){*n1=0;*n2=0;while(*ch!='\0'){if(*ch='0'&&*ch='9'){(*n1)++;}else{(*n2)++;C语言重要资料范浩15}ch++;}}/*当函数需要给出多个结果的时候还可以使用全局变量*/voidstrLL(char*ch){while(*ch!='\0'){if(*ch='0'&&*ch='9'){numN++;}else{numC++;}ch++;}}main(){charc[20];intl;intnum1,num2;scanf(%s,c);//gets(c);l=strLen(c);printf(%d\n,l);s
本文标题:C语言_函数
链接地址:https://www.777doc.com/doc-2908772 .html