在第四周时候我们的作业中编写了一个计算素数和的程序
高亮的部分作用是判断i是不是素数,功能单纯,占用版面大,因此我们可以将它独立出来,稍微更改一下数字。
而主函数内我们也做些更改
至今我们就完成了将一个全部功能都在主函数下的程序分为专用函数和主函数的转变。由此我们就可以将功能性代码和执行性代码分开,实现代码复用,精简程序。
如果同样的功能使用几乎完全一样的代码,一直复制粘贴代码,进行code duplication,这是程序质量不良的一种表现
我们理解时可以与数学中的函数做类比,但是并不等同。
最外侧的大括号外的是函数头,而其内部包含的内容是函数体。这个大括号是不可以省略的
函数头中,最前面的int作为函数的返回类型,决定了函数返回值的数据类型。“isPrime”是函数名,后面的圆括号标志着isPrime是一个函数,其内部我们称之为参数表,我们用逗号分隔不同参数,参数由类型名和变量名配对组成。
知道了函数如何定义,我们如何调用它?我们需要给出函数名+(传入给函数的参数值),确定要调用的是哪个函数,然后再依照正确的数量和顺序传递若干参数。这些值会被按顺序依次用于初始化函数中的值,当没有参数需要传入时圆括号依旧不能省略。
(按顺序传递信息)
(括号不能省略)
当需要多次调用同一函数时,每次调用完函数后函数会回到正确的位置。接下来还会细讲
每个主函数中我们写的return 0和上面函数例子中的return ret,都是根据需要返回了一个值。有一个例子可以帮助我们认识这一点。
这是一个单一出口的程序,遇到return程序停止运行,如果后面跟了东西就会返回这个东西。可以是值,也可以是表达式。
我们在之前的例子中看到,函数是写在主函数main之前的。这是因为C的编译器是从上往下顺序分析你的代码。在调用之前它需要知道函数的具体信息,同时检查你的调用是否正确。
如果想要将函数写在后面,可以在main之前写上函数头,以分号结尾。这称为函数的声明部分。也叫函数原型。
上图从上到下依次为: 调用字面量(常数);调用变量;变量+字面量;调用返回值+变量;计算结果+变量。
C编译器会悄悄帮你把类型转换好,即使和你所期望的不同,也就是说当你出错了,程序大概率会继续运行。这是C传统上最大的漏洞,C++和Java在这方面上会很严格。
C语言在调用函数时,永远只能将值传递给函数,也就是说,不能把变量传递给函数来改变主函数里变量的值。
举个例子,假如我们像这样写一个程序。把交换两个变量的值写成一个函数,然后在主函数里调用,这样做并不能交换两个数的值
虽然swap函数里的a,b和主函数里a,b同名,但它们是分别独立的,没有关系的。也就是说,每个函数都有自己的变量空间,参数也位于这个独立的空间里,和其他函数没有关系,独立的变量不能跨界。之后我们会详细讲讲这件事。
在过去我们把函数参数表里的参数叫做形参,把调用时候给的值叫做实参。由于容易让初学者误会实参是实际运算的参数,调用时候是把变量传递进去了,所以不建议这样称呼它们。这种称呼来自于第一种高级编程语言Fortran,因为它包含了将变量传递到函数的方式。但是C语言没有,所以我们可以认为传递的只有参数和值的区别。
因此我们可以将定义时候的参数称为参数,调用时候输入的称为值。
函数每次运行,都会产生一个独立的变量空间,在这个空间中的变量,是函数此次运行独有的,我们称其为本地变量(局部变量/自动变量)。
对于本地变量,二者的答案统一:在大括号(也可称为块)内(无论包含了多少语句)
哪个对?答案是第一个。为什么?
前面我们提到,如果你不写参数表,调用时C编译器会猜测你这里需要的类型,即使你并不想用这个类型。不写,不代表没有,只能说未知。因此调用时也许就会出错
答:是单纯的标点符号,不是运算符
答:不能,C语言规定 函数里不能嵌套定义另一个函数 。可以放声明部分或者调用别的函数。
如:int i,j,sum(int a,int b);
答:可以,但不建议。
答:可以,但不建议,会让人误以为return是个函数名
答:是的,主函数main也是一个函数,是整个程序的入口,但不是最先执行的代码,当一些先决代码被执行后就会开始执行main函数。
对于return 0,main函数结束的时候将这个0返回给调用它的地方,让其检查程序,报告给操作系统。返回0意思是程序正确执行并结束