抽象,就是由具体的例子范化到更一般的情况,抽象对计算机学科是非常重要的。以我们学习的函数为例,实际就是观察到有些操作反复使用,我们将其抽象成一个功能模块,使其只写一次就可以多次调用。可以参见
http://en.wikipedia.org/wiki/Abstraction_principle_(computer_programming)。
现在我们有一组数,int arr[N] = {1, 2, 3, 4, 5}; 希望输出格式如下
1 2 3 4 5
OnlineJudge的题目一般要求5后面没有空格,然后换行。所以下面的代码不行:
1 #include <stdio.h> 2 #define N 5 3 int main(void) 4 { 5 int i, arr[N] = {1, 2, 3, 4, 5}; 6 for(i = 0; i < N; i++) 7 printf("%d ", arr[i]); 8 printf("\n"); 9 return 0; 10 }
我写过下面的代码,第一个元素单独处理,随后的元素前面都有一个空格,最后再来一个换行。
1 #include <stdio.h> 2 #define N 5 3 int main(void) 4 { 5 int i, arr[N] = {1, 2, 3, 4, 5}; 6 printf("%d", arr[0]); 7 for(i = 1; i < N; i++) 8 printf(" %d", arr[i]); 9 printf("\n"); 10 return 0; 11 }
是不是感觉不清爽,没错,小小的一个功能居然分了三种情况。也许,最后一个元素才应该被区别对待,看下面的代码
1 #include <stdio.h> 2 #define N 5 3 int main(void) 4 { 5 int i, arr[N] = {1, 2, 3, 4, 5}; 6 for(i = 0; i < N - 1; i++) 7 printf("%d ", arr[i]); 8 printf("%d\n", arr[N - 1]); 9 return 0; 10 }
确实少了一个printf,只有两个情况。 能不能再统一呢? 注意到空格和换行都是字符,可以得到如下的抽象:
每输出一个元素后都希望接一个分隔字符
1 #include <stdio.h> 2 #define N 5 3 int main(void) 4 { 5 int i, arr[N] = {1, 2, 3, 4, 5}; 6 for(i = 0; i < N; i++) 7 printf("%d%c", arr[i], i == N - 1 ? '\n' : ' '); 8 return 0; 9 }
%c 是一个绝好的抽象,从具体的空格和换行符提升而来。我们很快意识到如果想输出
1,2,3,4,5
则只需要把空格换成逗号而已。这说明
具体的字符可能会变的,而分隔符才是这个问题更高层次的抽象