函数

相信大家对现在IT公司的项目完成方式都已经有所了解,一个项目的工作量绝不是一个人可以完成的,它是把这个项目里面的很多功能都一一拆解出来,然后交到一个个精英的手中,项目的最终产物一定是很多人努力成果的汇总。而想要实现这个过程,就得充分利用好函数的功能。

之前的章节我没有写总结是因为太简单了,没有必要写。有在函数方面薄弱的可以看看当复习,这篇文章是写给你们的,也是写给我自己的,方便四年后有考研想法的自己可以更好的复习。

函数的概念

函数是完成一个个特定任务的语句集合,它能完成你所想要的某种特定任务,当你想要用时,只需要调用它既可,在后续的修改或是维护过程中,只需要针对这一个进行修改即可。

函数的好处:

1.减少程序的代码量

2.代码复用

3.使程序有良好的结构

函数的结构包括两部分:函数头和函数体。其中函数数头又分为返回值数字类型,函数名和形参列表。

返回值数字类型:你在调用的函数中要返回给主函数的类型

函数名:随便起,但不能起重复。否则计算机会报错重定义

形参列表:这个是从主函数输给调用函数的值的类型

简单的例子(用函数输出hello luo teacher)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
void fun(void);//函数的声明,不要漏掉后面的;
//注意如果你要调用的函数在主函数的后面那就必须在头文件进行声明,否则计算机没办法调用
//主函数,要注意的是每一个程序都必须有一个主函数,否则计算机在执行程序时没有入口。
int main(void)//void表示空的意思
{
fun();//函数的调用,注意函数如果不被调用则不会被运行
return 0;
}

/*函数最好有注释让别人知道你调用的这个函数有什么用,别像那些被炒鱿鱼的程序员一样,把注释都删掉,
不管这个函数是不是简单,写注释都是我们必须有的好习惯,方便别人也方便自己*/
//功能:输出hello luo teacher
void fun(void)
/*fun是函数名,必须符合函数名的规则,建议首个英语单词首字母不大写,第二个此首字母大写,最好起个跟你这个函数功能相关联的,好记忆*/
{
printf("hello luo teacher");
}

这个程序很简单,所以放在这里当例子了。

函数声明的好处:

  1. 函数列表更加一目了然,方便使用。
  2. 便于多人共同合作开发
  3. 可以用于商业,保护知识产权(只将调用方式告诉他人,但是函数中具体的实现算法隐藏)。

通过增加函数来输出20+11的值

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int add(int a, int b);
int main()
{
int sum;
sum = add(20, 11);
printf("%d\n", sum);
return 0;
}

int add(int a, int b)
{
int c;
c = a + b;
return c;
}

为了这个程序没有那么古板你可以改一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
int add(int a, int b);
int main()
{
int sum,q,w;
printf("请输入要相加的两个整数");
scanf_s("%d %d", &q, &w);
sum = add(q, w);
printf("%d\n", sum);
return 0;
}

/**
* ┏┓   ┏┓
* ┏┛┻━━━┛┻┓
* ┃       ┃
* ┃   ━   ┃
* ┃ >   < ┃
* ┃       ┃
* ┃... ⌒ ... ┃
* ┃       ┃
* ┗━┓   ┏━┛
* ┃   ┃ 
* ┃   ┃
* ┃   ┃
* ┃   ┃ 神兽保佑
* ┃   ┃ 代码无bug  
* ┃   ┃
* ┃   ┗━━━┓
* ┃       ┣┓
* ┃       ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
//函数功能:计算A+B的值
int /*返回值类型是int所以返回值也必须是整形*/ add(int a, int b)/*输入的数也必须是整型*/
{
int c;
c = a + b;
return c;
}

有人可能会有疑惑为什么不把输入的这个步骤也放在函数内,我曾经也有过这个想法,但是主函数并不是越简单越好的,我更喜欢把要调用的函数称为模块,一个模块的核心原则是功能简单,越单一越好,功能越单一说明它的通用性越强,模块可以供更多的人去使用。

例题:定义一个函数,输出1~100之间的数据

分析:这个函数中所需要的数据已经唯一确定,不要其他函数传递数据进行辅助计算。

故:该函数的定义不需要形式参数,不需要返回值,函数中需要实现的就是输出数据(数据变化的),建议使用循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
void printf(void);
int main(void)
{
printf();//调用函数不需要写返回值
}
/**
* ━━━━━━神兽出没━━━━━━
*    ┏┓   ┏┓
*   ┏┛┻━━━┛┻┓
*   ┃       ┃
*   ┃   ━   ┃
*   ┃ ┳┛ ┗┳ ┃
*   ┃       ┃
*   ┃   ┻   ┃
*   ┃       ┃
*   ┗━┓   ┏━┛
*     ┃   ┃ 神兽保佑
*     ┃   ┃ 代码无bug  
*     ┃   ┗━━━┓
*     ┃       ┣┓
*     ┃       ┏┛
*     ┗┓┓┏━┳┓┏┛
*      ┃┫┫ ┃┫┫
*      ┗┻┛ ┗┻┛
* ━━━━━━感觉萌萌哒━━━━━━
*/
//输出1~10之间的数据
void printf(void)
{
int i;
for (i = 1;i <= 10;i++)
{
printf("%d\n", i);
}
return ;
}

定义一个函数输出1 * 2 * 3 * 4 * ···· * n的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<stdio.h>
int classq(int n);
int main(void)
{
int n,m;
printf("请输入n的值:");
scanf_s("%d", &n);
m = classq(n);
printf("1*2*3*...*%d的值为:%d", n,m);

return 0;
}
/**
**************************************************************
* *
* .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-. *
* | ______ | *
* | .-" "-. | *
* | / \ | *
* | _ | | _ | *
* | ( \ |, .-. .-. ,| / ) | *
* | > "=._ | )(__/ \__)( | _.=" < | *
* | (_/"=._"=._ |/ /\ \| _.="_.="\_) | *
* | "=._"(_ ^^ _)"_.=" | *
* | "=\__|IIIIII|__/=" | *
* | _.="| \IIIIII/ |"=._ | *
* | _ _.="_.="\ /"=._"=._ _ | *
* | ( \_.="_.=" `--------` "=._"=._/ ) | *
* | > _.=" "=._ < | *
* | (_/ \_) | *
* | | *
* '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=' *
* *
* LASCIATE OGNI SPERANZA, VOI CH'ENTRATE *
**************************************************************
*/
//输出1 * 2 * 3 * 4 * ···· * n的值
int classq(int n)
{
int i;
int a=1;
for (i = 1;i <= n;i++)
{
a = a * i;
}

return a;
}

函数的设计原则

  1. 一个函数实现一个功能
  2. 返回值的原则:如果计算有结果需要加返回值
  3. 形参的设计及原则:如果计算的过程需要有数值进行辅助,则需要加参数。
  4. 如果函数有形式参数则必须进行参数检查,检查参数是否有异常。
    通常用分支结构(选择结构)进行参数检查,如果有错误则返回。
  5. 函数体的设计思路
    第一步:定义变量
    第二步:逻辑关系运用,选择结构还是循环结构还是综合运用。