上篇博文已经回顾了内存分配方式的相关知识,特别是动态分配,此处我们以一个实例来练习体会一下动态分配的魅力。此例来自《程序设计抽象思想--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)体会动态数组的初始化,内存空间的显式申请和释放过程