iOS开发学习(4)之C语言函数

来源:转载


一、函数的定义
1.1函数的作用:

在程序设计语言中,函数是一个可以重复使用的、功能相对独立完整的代码片段。C程序是由函数组成的,函数是C程序的基本单元。C程序都包含一个main函数,即主函数,一个C源程序必须有一个也只能有一个main函数。在实际应用中,一个C程序中可以包含多个函数。main()函数可以调用其它函数,但不能被其他函数所调用,整个程序从主函数开始执行。



1.2自定义函数的书写格式:


用户定义函数:由用户自己写的函数。对于用户自定义函数,不仅要在程序中定义函数本身,而且在主程序中需声明,然后才能使用。
返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,…)
{
函数体
}

示例:
int main(){
}
void test1(){
}

二、函数的分类:**

从函数定义的角度看,可分为库函数和用户自定义的函数两种



2.1库函数



(1)由于太多不在这里一一列出:
参考链接地址:http://baike.baidu.com/view/2315895.htm


2.2用户自定义函数:

目的:将一个常用的功能封装起来,方便以后调用



2.3定义函数的步骤:


(1)函数名:函数叫什么名字
(2)函数体:函数是干啥的,里面包含了什么代码
(3)返回值类型: 函数执行完毕返回什么和调用者

2.4自定义函数:

(1)无参无返回值函数定义



格式:


void 函数名()
{
函数体
}

示例:
void sayHello()
{
printf("lnj hello");
}

没有返回值时return可以省略


(2)无参有返回值函数定义



格式:


返回值类型 函数名()
{
函数体
return 0;
}


示例:


int getAge()
{
return 30;
}



(3)有参无返回值函数定义
格式:
void 函数名(参数类型 形式参数1,参数类型 形式参数2,…)
{
函数体
}

示例:
void prtLines(int n)
{
for (int i=0; i<n; i++) {
printf("------");
}
}

形式参数表列表的格式:类型 变量名,类型 变量2,.......

(4)有参有返回值函数定义
格式:
返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,…)
{
函数体
return 0;
}

示例:
int getMax(int number1, int number2)
{
return number1 > number2 ? number1 : number2;
}



2.4函数定义注意:
函数不能嵌套定义
void test(){
void test2() // 错误写法
{
}
}


三、函数的参数
3.1形式参数介绍和使用:
基本概念:
(1)形式参数:在定义函数时,函数名后面的小括号()中定义的变量称为形式参数,简称形参

(2)形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。



示例:


int max(int number1, int number2) // 形式参数
{
return number1 > number2 ? number1 : number2;
}



3.2实际参数介绍和使用:
基本概念:
(1)实际参数:在调用函数时传入的值称为实际参数,简称实参

(2)形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。



示例:


int main()
{
max(88, 99); // 实际参数
return 0;
}


3.3形式参数、实际参数注意点:



调用函数时传递的实参个数必须和函数的形参个数必须保持一致



示例:


int max(int number1, int number2) // 形式参数
{
return number1 > number2 ? number1 : number2;
}
int main()
{
max(88); // 报错
return 0;
}


当使用基本数据类型(char、int、float等)作为实参时,实参和形参之间只是值传递,修改形参的值并不影响到实参函数可以没有形参



示例:


void change(int number1, int number2) // 形式参数
{
number1 = 250; // 不会影响实参
number2 = 222;
}
int main()
{
int a = 88;
int b = 99;
change(a, b);
printf("a = %d, b = %d", a, b);
return 0;
}
输出结果: 88, 99


四、函数的声明
基本概念:
(1)在C语言中,函数的定义顺序是有讲究的:默认情况下,只有后面定义的函数才可以调用前面定义过的函数

(2)如果想把函数的定义写在main函数后面,而且main函数能正常调用这些函数,那就必须在main函数的前面进行函数的声明



4.1函数的声明格式:


(1) 返回值类型 被调函数名( 类型 形参, 类型 形参... );

(2) 返回值类型 被调函数名( 类型, 类型...);



示例;



例如:
int max( int a, int b );
int max( int, int );

4.2函数的声明与实现的关系


函数的声明与实现的关系

注意点:

如果被调函数的返回值是整型时,可以不对被调函数作说明,而直接调用。这时系统将自动对被调函数返回值按整型处理



示例:



int main(int argc, const char * argv[])
{
printf("result = %d/n", getMin());
return 0;
}
int getMin() // 返回int, 不用声明
{
return 10;
}
int getMax() // 返回不是int, 需要声明
{
return 10.10;
}

当被调函数的函数定义出现在主调函数之前时,在主调函数中也可以不对被调函数再作说明而 直接调用。
示例:
float getMax() // 在调用之前定义
{
return 10.10;
}
int main(int argc, const char * argv[])
{
printf("result = %f/n", getMax());
return 0;
}

五、函数的调用
5.1函数调用的一般形式为:
(1)函数名(实际参数表);
(2)对无参函数调用时则无实际参数表。
(3)实际参数表中的参数可以是常数,变量或其它构造类型数据及表达式。

(4)多个参数各实参之间用逗号分隔。



函数表达式



函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数 是有返回值的。



示例:


int z=0;
z = max(23, 80) + 1; // 函数表达式

函数语句
函数调用的一般形式加上分号即构成函数语句
printf("%d",a);
scanf("%d",&b);

函数实参
函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因 此要求该函数必须是有返回值的。
printf("%d/n",max(20, 30));


5.2函数的嵌套调用
C语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下一级函数的问题。但是C语言允许在一个函数的定义中出现对另一个函数的调用。这样就出现了函数的嵌套调用。即在被调函数中又调用其它函数。这与其它语言的子程序嵌套的情形是类似的。其关系可表


函数关系表.png
六、递归函数
6.1递归函数概述及用法

一个函数在它的函数体内调用它自身称为递归调用。这种函数称为递归函数。C语言允许函数 的递归调用。在递归调用中,主调函数又是被调函数。执行递归函数将反复调用其自身,每调用 一次就进入新的一层。



示例:


void function(int x)
{
function(x);
}

这个函数是一个递归函数。但是运行该函数将无休止地调用其自身,这当然是不正确的。为了防 止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满 足某种条件后就不再作递归调用,然后逐层返回。

6.2递归函数构成条件
(1)自己调用自己
(2)存在一个条件能够让递归结束

(3)问题的规模能够缩小



示例:获取用户输入的数字, 直到用户输入一个正数为止


void getNumber()
{
int number = -1;
while (number < 0) {
printf("请输入一个正数/n");
scanf("%d", &number);
}
printf("number = %d/n", number);
}

void getNumber2()
{
int number = -1;
printf("请输入一个正数abc/n");
scanf("%d", &number);
if (number < 0) {
// 负数
getNumber2();
}else{
// 正数
printf("number = %d/n", number);
}
}

能用循环实现的功能,用递归都可以实现
递归就是自己搞自己,性能差
注意:递归一定要有一个明确的结束条件,否则会造成死循环

七、递归函数应用
7.1求第5个人年龄

有5个人坐在一起,问第5个人多少岁?他说比第4个人大两岁。问 第4个人岁数,他说比第3个人大两岁。问第3个人,又说比第2个 人大两岁。问第2个人,说比第1个人大两岁。最后问第1个人, 他说是10岁。请问第5个人多大?



分析



每一个人的年龄都比其前1个人的年龄大两岁。即:
age(5)=age(4)+2
age(4)=age(3)+2
age(3)=age(2)+2
age(2)=age(1)+2
age(1)=10
可以用式子表述如下:
如果(n=1)
age(1)=10
如果(n>1)
age(n)=age(n-1)+2


7-1

实现
int getAge(int n)
{
int age ;
if(n==1){
age = 10;
}else{
age = getAge(n-1)+2;
}
return age;
}


7.2用递归法求N的阶乘
分析
 4!=4*3*2*1
=4*3!
=4*3*2!
=4*3*2*1!
n!=(n-1)!*n;
(n-1)!=(n-2)!*(n-1);
... ...
1!=1; 作为递归的结束条件


7-2

实现
int factorial(int n){
int result = 0; //定义变量用于存放阶乘的结果
if (n==1) { //如果n=1的时候,1!的结果还是1
result = 1;
}else{
result = factorial(n-1)*n;//如果不是1,阶乘=(n-1)!*n;
}
return result;
}


7.3设计一个函数用来计算B的n次方

分析


 result = 1;
result = b
result = result * b
result = result * b
myPow2(b, 0) = 1
myPow2(b, 1) = b == myPow2(b, 0) * b
myPow2(b, 2) = b * b == myPow2(b, 1) * b
myPow2(b, 3) = b * b * b == myPow2(b, 2) * b


实现


int myPow2(int base, int n)
{
if (n <= 0) {
return 1;
}
return myPow2(base, n - 1) * base;
}


八、#include指令


8.1include基本概念
#include 是C语言的预处理指令之一,所谓预处理,就是在编译之前做的处理,预处理指令一般以 # 开头


#include 指令后面会跟着一个文件名,预处理器发现 #include 指令后,就会根据文件名去查找文件,并把这个文件的内容包含到当前文件中。被包含文件中的文本将替换源文件中的 #include 指令,就像你把被包含文件中的全部内容拷贝到这个 #include 指令所在的位置一样。所以第一行指令的作用是将stdio.h文件里面的所有内容拷贝到第一行中。

如果被包含的文件拓展名为.h,我们称之为"头文件"(Header File),头文件可以用来声明函数,要想使用这些函数,就必须先用 #include 指令包含函数所在的头文件

#include 指令不仅仅限于.h头文件,可以包含任何编译器能识别的C/C++代码文件,包括.c、.hpp、.cpp等,甚至.txt、.abc等等都可以


8.2文件包含的格式
当包含我们自己写的文件就是使用 #include "" 当包含系统

分享给朋友:
您可能感兴趣的文章:
随机阅读: