上次课,我们学习了字符数组,在最后,我们留下了一个思考题:
字符串的逆序
问题描述完成字符串的逆序输出
输入格式字符串 “Hello, String!”
输出格式逆序结果 "!gnirtS ,olleH"
这道题是把字符串进行逆序 reverse处理,就是把原字符串反向输出。
代码片段是这样的:
#include <stdio.h>
int main() {
// 原字符串
char s[] = "Hello, World!";
// TODO 实现原字符串的逆序,并输出
}
你做出来了吗?
我们一起来分析一下,要求得这个字符数组的逆序,只要能实现从后向前的循环输出就可以了。
但是既然要用到循环,我们需要知道这个字符数组元素的个数,如果知道了元素的个数,我们就可以用 for 循环的方式来实现逆序。
于是问题转化为怎样求得这个字符数组的元素个数。这个并不难,我们也可以在一个循环中用一个计数器来计算字符的个数。
但是,循环何时结束呢,不然就陷入无限循环了...
别忘了,上次课,我们提到了一个 C 语言中字符数组很特别的一点,就是每个数组的最后一个元素总是 \0,而这,就是我们循环结束的标志!
到此为止,我们有了解决这个问题的整体思路,那就一步一步的来实现吧。
代码 1:#include <stdio.h>
int main() {
char s[] = "Hello, World!";
// 计数器,同时作为索引
int count = 0;
while (s[count] != '\0') {
count++;
}
printf("%d", count); // 输出:13
// TODO 实现原字符串的逆序,并输出
}
这样,我们求得了字符数组元素的个数 13。
代码 2:#include <stdio.h>
int main() {
char s[] = "Hello, World!";
int count = 0;
while (s[count] != '\0') {
count++;
}
// TODO 实现原字符串的逆序,并输出
// 定义逆序数组 r
char r[count + 1];
// 用 for 循环实现 s 的逆序,赋值给 r
for (int i = 0; i < count; i++) {
r[i] = s[count - i - 1];
}
printf("%s", r); // 输出 !dlroW ,olleH
}
这样,我们就求得了 s 数组的逆序数组 r,并实现了输出。
问题是,现在这个代码过程只是把 “Hello, World!” 实现了逆序,如果换一个字符串,代码还需要做更改才可以,能不能避免这种重复性的操作呢?
让我们来探索一下 C 语言的函数,它可以解决这个问题。
函数 function 是 C 语言中非常重要的一个内容,任何的高级计算机语言都有函数的存在。
那什么是函数呢?
函数就是可以执行一个特定任务的代码块:
函数在数学中为两个不为空集的集合间的一种对应关系:输入值集合中的每项元素皆能对应唯一一项输出值集合中的元素。
Wikipedia
函数就像机器,给予输入产生输出
我们可以把函数看作一个“黑箱”,不必关注里面做了什么,只要了解这个黑箱需要什么输入,能够产生什么输出就可以,这样,这个函数就可以为我们所用。
其实,我们第一天写代码时,就已经接触过 C 语言的函数了:
C语言的基本结构单位是函数。
系统首先调用 main 函数(主函数),通过函数的嵌套调用,再调用其他函数。
函数可以是系统自带的函数,也可以是用户定义的函数。
Wikipedia
看到了吗?我们每次写的 int main(){} 就是 C 语言的一个函数,它是一个程序执行任务的开始。
而我们更加频繁使用的 printf() 也就是一个 C 语言的标准库函数,它被定义在头文件 header file stdio.h 中,所以,我们要做输出,必须引入这个头文件:
#include <stdio.h>
是不是更加清楚了我们代码的主体结构?
在 C 语言中,函数分为两大类:
我们来学习一个跟数学运算有关的库函数:sqrt() 是定义在头文件 math.h 中的一个库函数,它的作用是求一个数的平方根。
好,我们来测试一下:
#include <stdio.h>
#include <math.h>
int main() {
double d = 9.0;
double r = sqrt(d);
printf("%lf", r); // 输出 3.000000
}
很快,我们得到了 9 的平方根。
函数的作用使用函数有什么好处呢?
作用体现在很多方面,我们来了解一下函数比较明显的几个优势:
所以,重视函数,学好函数是开发大型程序的必要条件。
除了我们可以使用的大量的 C 语言标准库函数之外,我们在实际的编程过程中,更需要根据具体的需求编写属于我们自己的函数。
这意味着,我们不仅要会用函数,也需要会写函数,而这就是 C 语言的自定义函数。
那么,怎样来自己定义一个函数呢?
在 C 语言中,一个函数一般有以下几个部分组成:
返回类型 函数名(类型1 参数1, 类型2 参数2, ...) {
// 函数体
返回控制
}
看起来好像很复杂?我们先来定义一个函数:
int sum(int x, int y) {
int z = x + y;
return z;
}
这样我们就定义了一个计算两个整数之和的函数,从这个函数中,我们需要了解到:
这样,我们就完整的了解了一个 C 语言函数的定义过程。
在函数定义完成后,我们就可以使用这个函数了,这个过程叫做调用 calling:
#include <stdio.h>
int sum(int x, int y) {
int z = x + y;
return z;
}
int main() {
printf("%d", sum(1, 2)); // 输出 3
}
我们在主函数 main() 中调用了函数 sum(),求得了 1 和 2 的和,得到了结果。
需要注意的是,在 C 语言中,函数的参数是可有可无的,函数的返回值也是可有可无的,因此,根据这一点,C 的函数又分为了这样几种类型:
那么,在实际编程过程中,我们到底要使用哪一种类型呢?
答案很简单:一切依据你的需要来,代码是死板的,编写代码的我们是灵活的~
最后一个思考题:实现用户输入的任意字符串的逆序,把这个逆序的过程编写为函数,试一下吧!