下面介绍一个C语言中非常重要的概念——函数。首先,我们需要给函数一个定义。函数是完成特定任务的独立代码单元。也就是说,必须要用一个函数来完成某个功能。例如,函数可以执行加法运算。例如,一个函数可以交换两个数字的值,有些函数可能只是打印一些东西等等。函数也可以将很多大任务拆分成小任务,设计每个小任务来完成一个大的功能。一个设计良好的功能可以隐藏程序中不需要理解的细节,从而使整个程序结构更加清晰,降低程序修改的难度。一个C语言程序由许多小函数组成。一个程序存储在多个源文件中。每个文件都可以单独编译并与库中的编译函数一起加载。让我们用一个例子来讨论函数是如何创建和使用的。函数的创建和使用函数的创建和使用会分为三个步骤:函数原型(函数类型):这是创建一个函数定义,也叫函数声明,它可以指明一个文件中有哪些函数。函数调用(functioncall):调用函数的位置。函数已定义且必须使用。那里使用的函数称为函数调用。函数定义(functiondefinition):这个就是函数具体干什么的,也就是函数的具体逻辑是什么。这样看,函数和变量完全一样。函数需要原型、调用和定义,变量也需要这些,但变量也可以将原型和定义一起表达。#includeintnum;//变量原型intsum(int,int);//函数原型intmain(void){num=12;//变量定义intnum2=11;//函数原型+函数定义intall=sum(num,num2);//变量使用,函数使用printf("all=%d",all);return0;}//函数定义intsum(inta,intb){returna+b;}上面的代码很好地说明了变量的定义和函数的定义。我们先定义一个num变量,这是变量的原型,然后在main函数中使用这个变量,就是变量的定义和使用。当然变量也可以直接使用原型+定义(上面的num2),sum函数演示涵盖了函数的原型、定义和使用。这里要注意main函数比较特殊,它是所有方法的入口,不定义原型就可以直接使用main函数。以上代码一起保存在一个文件中。当然,你也可以将它们保存在不同的文件中,但为了我们的演示,将它们放在同一个文件中更方便。还有一点就是它们可以一起进行。编译。这两个函数也可以定义在不同的文件中,分别编译。这样做的好处是程序更容易维护,代码阅读起来更流畅。其实项目中也使用了单独编译的方式。当然你也可以把所有的功能都写在main函数里面,但是这样不便于维护,也不符合项目开发的标准。一个完整的函数定义是这样的:返回值类型函数名(参数列表){函数体(函数的具体功能)}注意,我们上面说的只是一个完整的函数定义,并不是每个函数都必须有返回值类型,参数列表,函数体,只需要函数名(这个一定要通俗易懂)。当然也有什么都不做就定义的函数,相当于一个空函数。C语言默认允许出现空函数。例如,下面的函数是一个空函数。sort(){}排序函数不执行任何操作,也不返回任何值。该功能可以在程序开发时使用,为以后填入代码预留位置。程序实际上是变量和函数的集合。函数之间的通信可以通过函数参数和返回值来完成。函数传递参数,进行一系列逻辑运算,然后返回返回值,实现函数通信。沟通的目的。对于函数,我们需要了解的两个关键点是参数列表和返回值。函数参数对于上面的sum函数,函数参数有两个,分别是int类型的a和b。像这样在函数定义的括号中的变量称为函数参数。a和b这两个变量也称为形参,简称形参。和函数中定义的变量一样,形参也是局部变量,是函数私有的,作用范围从进入函数开始到函数执行结束。当函数接受参数时,函数原型以逗号分隔的列表指示参数的数量和类型,您可以使用以下方法定义函数原型。整数总和(整数a,整数b);//函数原型也可以省略具体的变量名,按照下面的方式定义。整数总和(整数,整数);//函数原型在函数原型中没有定义变量,只声明了两个int类型的参数。除了形参之外,还有一个概念叫做实参(actualparameters),对应上面代码中的sum(num,num2),因为在调用sum的时候就知道了num和num2的具体值,像这样在调用函数中给形参传值的形参称为实参。简单来说,形参就是被调用函数中的变量,实参就是调用函数赋给被调用函数的具体值。实际参数可以是常量、变量,甚至更复杂的表达式。被调用函数不知道也不关心传入的值是来自常量、变量还是一般表达式。实参将值传给函数时,实际上是将值复制到被调用函数的形参中,所以无论被调用函数对复制的数据进行什么操作,都不会影响调用函数中的原始数据.如下代码所示:#includeintnum;//变量原型voidsum(int,int);//函数原型intmain(void){num=12;//变量定义intnum2=11;//函数原型+函数定义sum(num,num2);//变量使用,函数使用printf("num=%d,num2=%d",num,num2);return0;}//函数定义voidsum(inta,intb){intsumAll=a+b;printf("sumAll=%d\n",sumAll);}从输出结果可以看出,只要将值传递给sum,无论sum函数内部做了什么处理,都不会影响main函数中num和num2的值。函数返回值上面我们说过,函数之间的通信可以通过函数参数和返回值来进行。函数参数传递的方向是函数调用者->被调用函数,函数返回值的方向与参数传递的方向相反,即被调用函数->函数调用者。当然,并不是所有的函数都需要返回值,return语句后也不一定需要表达式。当return语句后没有表达式时,函数将不会向调用者返回值。返回值将被传递。return表达式返回,返回值的表达式类型与函数定义的返回值类型一致。我们还以上面的求和函数为例:intsum(inta,intb){returna+b;}可以看到求和函数的表达式返回a+b,其实就是一个表达式。而我们可以看到上面的intmain方法,它的返回值为0,也就是说它返回的是一个常量。return后可以不返回任何值,也可以只写一个return,但这种方法相当于不返回任何值,所以其函数类型可以定义为void,如下代码所示://函数定义voidsum(inta,intb){intsumAll=a+b;printf("sumAll=%d\n",sumAll);返回;}使用return语句的另一个作用是终止函数的执行,强制控制权返回给调用者Function,如下代码所示://Functiondefinitionintsum(inta,intb){intsumAll=a+b;printf("sumAll=%d\n",sumAll);如果(a+b>0){返回总和;}else{返回0;}}如果a+b的值大于0,则直接返回a+b之和,否则为0。这个if的控制流程是强制将结果返回给函数调用者。如果在if控制流之后添加代码,那么这段代码不会执行,但是编译也不会给出警告。在Java编辑器中,如果最后一行代码出现在returnmandatoryreturn之后,编译器会给出警告或错误提示,这行代码不会被执行。函数类型这里需要再次强调一下函数类型。定义函数时,需要声明函数的类型。具有返回值的函数的类型与返回值的类型相同。没有返回值的函数应定义为void类型。在老版本的C编译器中,如果不声明函数类型,编译器会默认把函数当做int类型,不过这是很早的事情了,现在C标准已经不支持默认函数为一个int类型。情况。在写函数的时候,需要考虑函数的具体作用是什么,即这个函数是干什么的,是否需要返回值,如果需要返回值,它的返回类型是什么。函数声明如果你学过Java,你可能不习惯C的先声明再定义的方式。为什么函数在定义之前需要单独声明?我不声明直接定义函数可以吗?答案肯定不是。这种使用前的声明一直是C语言的标准。没有标准的原因。这是一个标准,但是这个标准是一个历史问题。在20世纪70年代,大多数计算机内存非常小,处理速度相对较差,导致代码运行时间长,效率低下。这时候就需要考虑内存占用和编译时间。因为C语言发展比较早,C直接和硬件打交道,所以提前声明函数可以提前分配内存空间,提高效率。说白了,还是效率的问题。而C语言为什么不选择使用预编译呢?参考自https://www.zhihu.com/question/20567689首先,C语言出现的时间很早。那时候编译器也是一个很复杂的东西。那时候电脑的内存和外存都很小,编译器做的太大也是一件麻烦的事情,所以事先的声明就变成了规范,保留下来是为了让编译器更简单,虽然这一切非常过时。其次,预编译的成本非常高。与脚本语言和解释语言不同,C语言的项目规模可以非常大。例如,一个操作系统级别的C语言项目,有数万个源文件和数十万个全局符号。首先,预编译这种规模的项目的负担非常高。如果把整个工程全部扫描一遍,遍历所有的全局符号,再进行真正的编译,估计很多coder会抓狂,等待的时间会特别长。同样,C语言是静态链接语言。如果一个项目设计成只编译不链接,比如有些库会设计成这样。在一些合作开发的项目中,团队成员有时如果只提供了obj文件,那么有些全局符号可能在现有代码中没有包含,有些符号在预搜索中一定找不到,那怎么办呢?如果您不提供声明,代码将无法编译。基于以上考虑,C语言就是这样设计的。对于开发者来说,不算友好,但也不算太坏,甚至在某些方面是有好处的。对于一个函数来说,它的最终目的是通过一系列的逻辑处理得到我们想要的结果。逻辑处理离不开各种程序控制语句,比如While、for、dowhile等,接下来我们就来讨论一下这些程序控制语句。程序控制语句在某些程序中有时可能会重复做一件事情,所以应该允许计算机做这些重复的工作。这就是我们需要计算机的意义。毕竟,需要重复计算是使用计算机的主要原因。C语言中有很多重复计算的方法。我们先介绍其中的一个---while循环。while循环下面通过一段代码来看看while循环的使用。#includeintmain(){inti=1;while(i<=10){printf("%d\n",i);我++;}return0;}这段代码先声明了一个i变量,然后用while循环判断i的值,当i的值<=10时,执行while中的循环逻辑,否则i>10,直接跳过循环,不输出任何结果,直接返回0。如果i的值在10以内,则循环打印出i的值。这就是while循环的作用。用通俗易懂的语句来描述while循环:当某个判断条件为真时,执行while循环中的代码块。流程图如下:while循环中的一个关键点是进入while循环的判断。上面的代码是判断i<=10,这个表达式是一种关系运算符。while循环通常依赖测试表达式进行比较。这样的表达式称为关系表达式,出现在关系表达式中间的运算符称为关系运算符。下表显示了我们经常使用的关系运算符。运算符说明<小于<=小于等于==等于>=大于等于>大于!=不等于这些运算符不仅会出现在while循环中,实际上任何逻辑控制语句都会用到这些类型的运算符号。这里需要说明一下,不能使用关系运算符来比较字符串,比如ch!='@'。虽然关系运算符可用于比较浮点数,但要注意:比较浮点数时,尽量只使用<和>。由于浮点数的舍入误差,逻辑上应该相等的两个数并不相等。例如,3乘以1/3的乘积是1.0。如果1/3表示为小数点后6位,则乘积为.999999,不等于1。for循环一个很明显的特点就是把三个行为结合在一个地方,即初始化、判断,并更新,如以下代码所示。#includeintmain(){for(inti=1;i<=10;i++){printf("%d\n",i);}return0;}可以看到,上面代码中间的for循环分别做了三件事,每个表达式之间用;隔开。inti=0相当于初始化i;i<=10相当于对i进行逻辑判断,逻辑判断是判断是否进入下一个循环的关键。i++相当于更新i的值。for循环的一般形式定义如下:for(expression1;expression2;expression3){statement;}这里需要注意的是,表达式1在循环开始时只执行一次,而表达式3是循环结束后执行。可以省略表达式2。如果省略,默认值为1。如果判断为真,for循环就会变成死循环。for循环的流程图如下:dowhile循环一般来说,有两种循环:入口循环和出口循环。你是什??么意思?入口循环就是先循环,然后执行每个循环要做的事情,比如上面的while循环和for循环,都是先判断是否需要下一个循环,如果需要的话,i的值会被打印出来,这是入口循环。退出循环是先执行代码,然后判断是否进入下一个循环,即每次循环结束后检查测试条件,保证循环体内容至少执行一次.一个典型的退出循环是do。..尽管。我们修改上面的代码:#includeintmain(){inti=1;做{printf("%d\n",i);我++;}而(我<=10);return0;}从输出可以看出,dowhile循环在执行完循环体之后才执行测试条件,所以do...while循环至少执行一次循环体,而for循环和while循环执行循环体首先执行测试条件,do...while的一般形式如下docodewhile(expression);do...while循环流程图如下到现在为止,我们都已经了解了C语言中的程序控制语句,那么如何进行选择呢?其实上面我们已经稍微讨论过如何选择了。while循环与for循环非常相似。这两类循环都是先对循环条件进行一次判断,然后再执行具体的循环体操作。只要循环条件一次不满足,就不会执行一次;whiledo...while循环在执行循环判断之前至少会循环一次。一般来说,使用for循环的场景比较多,因为for循环的形式比较简洁,而且在for循环中,变量、判断、更新作用域都在循环体内,并且会有没有其他外部代码修改这些变量,更可控,在while和do...while循环中,变量的更新是不可控的,代码可读性不如for循环。break和continuebreak和continue相当于循环体中leader的作用。有了这两个作用,循环体内的代码就会根据这两个关键字来判断是中断循环还是执行下一个循环。break在C语言中有两种用法:一种是在循环体中使用,当循环体中出现break时,循环就会中断。一种用法是在switch语句中,作为中断switch语句的case条件。break用于中断循环:如下代码所示:#includeintmain(void){for(inti=1;i<=10;i++){if(i==5){休息;}printf("i的值=%d\n",i);}return0;}输出结果为i=1-4的值,当i==5时,会进入if判断,if判断会直接触发break,break用于跳出当前循环,目前是一个for循环,所以break会直接跳到for循环外,也就是直接return,不会打印i的值。continue关键字用于跳过当前循环并执行下一个循环。它与break类似,但又有本质区别。break是跳出循环,continue是执行下一个循环。更改中断以继续。#includeintmain(void){for(inti=1;i<=10;i++){if(i==5){继续;}printf("i值=%d\n",i);}return0;}(这段代码的输出会输出i=5以外的值)从输出可以看出只有i=5的值没有输出,也就是说,当代码当执行到i==5时,continue会继续执行当前循环,从而跳过本次循环后面的代码,如下图所示。总结一下这篇文章,主要和大家聊了聊C语言中的函数,函数定义,函数返回值,参数,以及程序控制流程中三种循环的特点和选择。最后介绍了break和continue的功能。.