上篇博文已经回顾了内存分配方式的相关知识,特别是动态分配,此处我们以一个实例来练习体会一下动态分配的魅力。此例来自《程序设计抽象思想--C语言描述》P77
代码示例:
/* findZhiShu.c --- * * Filename: findZhiShu.c * Description: 查找2~n之间的质数 * Author: magc * Maintainer: * Created: 四 8月 2 06:08:41 2012 (+0800) * Version: * Last-Updated: 四 8月 2 06:47:39 2012 (+0800) * By: magc * Update #: 51 * URL: * Keywords: * Compatibility: * */ /* Commentary: * 公元前3世纪,著名天文学家Eratosthenes发现一个在有上限N的数列中求质数的方法: *在算法开始时,先写出2到N的数列 * 然后圈出第一个数,表明找到一个质数,然后在余下的列表中划去刚圈出质数的倍数,(因为是倍数的一定不是质数) * 以此类推,每次圉出第一个数,划去其倍数 *最终该数列要么是被圈出,要么是被划掉,被圈出的便是所有质数。 * */ /* Change Log: * * */ /* Code: */ #include <assert.h> #include <ctype.h> #include <errno.h> #include <limits.h> #include <string.h> #include <stdarg.h> #include <stdlib.h> #include <stdio.h> void findzs(int *list,int len); int main(int argc, char * argv[]) { int n; printf("请输入整数n,将输出2~n之间的所有质数:\n"); scanf("%d",&n); printf("2~%d之间的质数有:\n",n); //初始化此动态数组的内容 int *list = malloc(sizeof(int) * (n-1)); if(list == NULL) error("no memory available\n"); int i; for (i = 0; i < n-1; i++) { list[i] = i + 2; } findzs(list,n-1); printf("\n"); } /************************************************************************** 函数名称: 功能描述:递归查找质数,查找思路查看前面Commentary内容 输入参数: 返 回: **************************************************************************/ void findzs(int *list,int len){ if(len<1)return; //递归结束的出口,不然陷入死循环的深渊 //创建另一个动态数组,来保存圈出或划掉剩下的数列,以供下次用同样方式操作。 int *res = malloc(sizeof(int) * len); if(res == NULL)error("no memory availabe"); int res_count = 0; printf("%d,",list[0]); int i; for (i = 1; i < len; i++) { if(list[i]%list[0]){ //若为第一元素的倍数,划掉即跳过(即放弃) res[res_count] = list[i]; res_count++; } } //及时释放不用的内存空间 free(list); findzs(res,res_count);//递归查找 } /* findZhiShu.c ends here */
注:
1)体会递归的玄妙,由命题分析易知,此问题的解决包含了一个重复的子问题,取第一元素,划去其倍数过程
2)把握递归过程的结束临界点,即为程序置一个出口。
3)体会动态数组的初始化,内存空间的显式申请和释放过程