0%

C语言 自定义函数

自定义函数是写大程序的前提

最开始写程序的时候,我们都会全部一股脑地写在main函数中,导致有的main函数有成千上万行,要调试起来,这就尴尬了。

这就引出了我们需要定义一些自定义函数,只需要将这些函数写在主函数就可以了。

是个什么意思呢,就是你秀给客户或者测试人员的main函数,是这个样子的(看一下百万量级规模的内核启动函数):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(void)
{
printf("Linux/AXP bootloader for Linux \n");

pal_init();

openboot();

printf("Loading vmlinux ...");
load(dev, START_ADDR, KERNEL_SIZE);
close(dev);

callback_getenv(ENV_BOOTED_OSFLAGS, envval, sizeof(envval));

runkernel();

//__halt();
}

虽然有些东西看不懂什么意思(因为我精简和修改了部分代码),没有问题,我们需要理解的就是Linux内核有百万行量级,而它的主函数也就短短的十几行,其他的就放在了自定义函数里实现,也就上面的openboot,runkernel等。


OK,任务来了,我想让你写个程序,计算出摄氏度和华氏度的转换,

两个的转换关系如下:

  • 华氏度 = 32°F+ 摄氏度 × 1.8
  • 摄氏度 = (华氏度 - 32°F) ÷ 1.8

这个简单呀,前面就写过(刷刷刷,码出如下代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*beginner/function/function1.c*/
# include <stdio.h>

int main()
{
float f; // Fahrenheit temperature
float c; // Celsius temperature

f = 80.0;
c = 27.0;

float ff;
float cc;

printf ("Fahrenheit <=> Celsius\n");
ff = 32 + c * 1.8;
cc = (f - 32) / 1.8;

printf("%f <=> %f\n",f, cc);
printf("%f <=> %f\n",ff, c);


return 0;
}

不错,孺子可教也,在加深一步,又来了一组数据,也是求两者的转换关系,代码继续累加,如下:

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
/*beginner/function/function2.c*/
# include <stdio.h>

int main()
{
float f; // Fahrenheit temperature
float f1;
float c; // Celsius temperature
float c1;

f = 80.0;
f1 = 90.0;
c = 27.0;
c1 = 36.0;

float ff;
float ff1;
float cc;
float cc1;

printf ("Fahrenheit <=> Celsius\n");
ff = 32 + c * 1.8;
cc = (f - 32) / 1.8;

printf("%f <=> %f\n",f, cc);
printf("%f <=> %f\n",ff, c);

ff1 = 32 + c1 * 1.8;
cc1 = (f1 - 32) / 1.8;

printf("%f <=> %f\n",f1, cc1);
printf("%f <=> %f\n",ff1, c1);

return 0;
}

如果我在来一组数据,是不是同样还需要在原来的代码基础上累加,我们就会发现:main函数越来越庞大,但是有效的代码就那么几行,其余的工作都是在重复叠加,这就引出一个问题,我们的华氏转摄氏度是比较简单的公示,如果算个麦克斯韦方程:

$\oiint_{\partial V}\mathrm{E}\cdot d \mathrm{a} = \frac{Q_V}{\epsilon_0}\ \oiint_{\partial S}\mathrm{E}\cdot d \mathrm{l} = \frac{d}{dt} \int_S \mathrm{B} \cdot d\mathrm{a}\ \oiint_{\partial V}\mathrm{B}\cdot d \mathrm{a} = 0 \ \oiint_{\partial S}\mathrm{B}\cdot d \mathrm{l} = \mu_0\epsilon_0\frac{d}{dt} \int_S \mathrm{E} \cdot d\mathrm{a} $$

其中$\oiint$为环路积分的符号

那么每一次计算都要重复这些操作,有没有一种方法可以简化呢,妥妥滴,这就带来了自定义函数。

我们以华氏度和摄氏度的转换为例,可以定义两个函数:

1
2
float c2f(float c); // Celsius to Fahrenheit
float f2c(float f); // Fahrenheit to Celsius

两个函数的含义为c2f就是将摄氏度c转换为华氏度返回,相反f2c为将华氏度f转换为摄氏度返回。

具体的代码如下:

1
2
3
4
5
6
7
8
9
float c2f(float c)
{
return 32 + c * 1.8;
}

float f2c(float f)
{
return (f - 32) / 1.8;
}

我们把这两个代码片段加到程序中,最后的效果如下:

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
/*beginner/function/function2.c*/
# include <stdio.h>

float c2f(float c); // Celsius to Fahrenheit
float f2c(float f); // Fahrenheit to Celsius

int main()
{
float f; // Fahrenheit temperature
float f1;
float c; // Celsius temperature
float c1;

f = 80.0;
f1 = 90.0;
c = 27.0;
c1 = 36.0;

float ff;
float ff1;
float cc;
float cc1;

printf ("Fahrenheit <=> Celsius\n");
cc = f2c(f);
ff = c2f(c);

printf("%f <=> %f\n",f, cc);
printf("%f <=> %f\n",ff, c);

cc1 = f2c(f1);
ff1 = c2f(c1);

printf("%f <=> %f\n",f1, cc1);
printf("%f <=> %f\n",ff1, c1);

return 0;
}

float c2f(float c)
{
return 32 + c * 1.8;
}
float f2c(float f)
{
return (f - 32) / 1.8;
}

这个程序新加的东西有点多,不过可以清晰的看到,主函数通过使用自定义的函数已经将重复的东西结构化了,这是编写大程序的基础,希望你能掌握。

编译运行

直接输入make就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#beginner/function/Makefile
ALL : function1 function2 function3

function1: function1.c
gcc -o function1 function1.c

function2: function2.c
gcc -o function2 function2.c

function3: function3.c
gcc -o function3 function3.c

.PHONY : clean

clean:
rm -f function1 function2 function3

运行输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ ./function1
Fahrenheit <=> Celsius
80.000000 <=> 26.666666
80.599998 <=> 27.000000

$ ./function2
Fahrenheit <=> Celsius
80.000000 <=> 26.666666
80.599998 <=> 27.000000
90.000000 <=> 32.222221
96.800003 <=> 36.000000

$ ./function3
Fahrenheit <=> Celsius
80.000000 <=> 26.666666
80.599998 <=> 27.000000
90.000000 <=> 32.222221
96.800003 <=> 36.000000
处无为之事,行不言之教;作而弗始,生而弗有,为而弗恃,功成不居!

欢迎关注我的其它发布渠道