使用C语言的递归

时间:2009-11-08 20:13:36

标签: c recursion

当我编译这个程序时,我只得到第一个大写字母而不是其他大写字母。

输入:

  

ABldjfdslkjfCK

我只能得到'A'吗?

#include <stdio.h>
#include <string.h>
FILE *fp;

int main(void)
{   
    int size; 
    char input[100]; // array size of 100 

    if (fp = fopen("message.txt","r")) // file exists
    {
        fgets(input,100,fp);// scans the sentence. 
    }
    else 
    {
    printf("file not found");// if there is no such a file. 
    }    

    size=strlen(input);  
    recursive(size,input); 

    return 0;
}

int recursive(int size, char array[])
{
    static int index = 0; // static so when the function is called, the  value is kept

    if (index < size) // start from index 0 until the size-1
    {
        if (array[index] >= 'A' && array[index] <= 'Z') // check for A to Z  (CAPITALIZE CHARACTERS only)
        {
            printf("%c\n", array[index]); // print it
        }
        else 
        {
            return recursive(size,array); // calls the function (recursion)
        }
    }
    return 0;
}

6 个答案:

答案 0 :(得分:14)

您永远不会增加index的值。此外,如果当前字符是大写字母,则不调用函数recursive,因此函数只返回。

不是为index使用静态变量,最好将其作为参数传递给recursive;否则,该函数是不可重入的。

答案 1 :(得分:4)

只有在找到非大写字符时,您的递归函数才会调用自身。当它找到第一个大写字母时,它会打印它并退出

答案 2 :(得分:3)

您当前的函数仅打印A,因为只要它找到一个大写字母(在您的情况下为A),它就会返回0.

还有其他问题,所以我会改写这样的函数:

#include <ctype.h>  /* for isupper */

void recursive(const char* s)
{
    /* stop condition: empty string */
    if (s[0] == '\0')
        return;
    /* main body: print letter if capital */
    if (isupper(s[0]))
        printf("%c\n", s[0]);
    /* recursion: advance to the next character */
    recursive(s + 1);
}

像这样使用:recursive(input)

答案 3 :(得分:3)

您的递归函数存在的其他问题是index变量是静态的。这在当前版本中不是问题,因为除了琐碎的方式之外你实际上并没有使用它。但是,一旦您尝试修复其他问题(这可能会导致您以更复杂的方式使用index),拥有static会产生一些问题:

  • 第一次使用后没有好的方法可以正确初始化它。这通常通过使用非递归“包装器”函数来修复,该函数初始化状态变量并将其传递给执行实际工作的私有递归函数(并将值作为参数而不是使用静态实例)。包装器启动了完成实际工作的功能。
  • 对函数的递归调用将修改静态变量,这将修改正在进行的递归调用的“已保存”实例的状态。如果递归是一种称为“尾递归”的类型,这可能不是问题,其中执行递归调用的调用者在递归调用返回后不会执行任何额外的工作,但并非所有递归函数都是尾递归。虽然你的例子很容易(但我仍然试图避免使用静态变量)。

答案 4 :(得分:2)

两个问题:

  1. 您正在错误地终止递归。你需要保持递归,直到到达数组的末尾。
  2. 您还有第二个问题,即您没有递增索引,因此每次调用都会始终查看第一个字符。

答案 5 :(得分:1)

我看到的第一个错误是你永远不会增加索引。