在C中递归排列字符串时,For循环会产生错误

时间:2019-01-24 14:34:17

标签: c recursion permutation

我是C语言的新手,正在尝试编写一个函数,该函数使用递归返回字符串大小为k的子集的所有排列。例如,对于字符串“ abc”和k = 1,我将得到“ a”,“ b”和“ c”,对于k = 2,我将得到“ aa”,“ ab”,“ ac”,“ ba” ','bb','bc','ca','cb'和'cc',依此类推。

我想返回所有生成的字符串,以便我可以对它们进行其他操作-现在它只是将它们打印出来,但是稍后我将使用它们。我写了这段代码:

-flto:
This option runs the standard link-time optimizer. When invoked with 
source code, it generates GIMPLE (one of GCC’s internal representations) 
and writes it to special ELF sections in the object file. When the object 
files are linked together, all the function bodies are read from these ELF 
sections and instantiated as if they had been part of the same translation 
unit.

但是,我收到错误信息'recur1.c:40:1:错误:控件可能到达非void函数的结尾       [-Werror,-Wreturn-type]'尝试进行编译时。

为了进一步探讨这一点,我删除了for循环,该循环导致字符串反转:

#include <stdio.h>
#include <string.h>

#define CHARS "abc"

char *recur(char* prefix, int k, int n);

int main(void)
{     
    int k = 2; //for example
    int n = strlen(CHARS); //set n as length of CHARS
    //print string generated by recur
    printf("string: %s\n", recur("", k, n));
}

char *recur(char *prefix, int k, int n)
{
    //if base case (have already added all letters), return string
    if (k == 0)
    {
        return prefix;
    }
    //otherwise, add character from CHARS to string
    else
    {
        for (int i = 0; i < n; i++)
        {
            // for each letter in CHARS, make a new prefix and add a letter from chars to it
            int prefLen = strlen(prefix);
            char newPrefix[prefLen + 2];
            strcpy(newPrefix, prefix);
            newPrefix[prefLen] = CHARS[i];
            newPrefix[prefLen + 1] = '\0';
            return recur(newPrefix, k-1, n);
        }
    }
}

替换第二个函数后,代码编译没有任何问题。关于为什么带有for循环的版本无法编译的任何想法?

2 个答案:

答案 0 :(得分:1)

如果n <= 0,则将永远不会进入for循环,因此,将永远不会到达循环主体中的return语句。由于循环后没有return语句,因此编译器会抱怨(正确的是)。

那是说:您确定在循环体内有无条件的return语句不是错误吗?这使循环变得毫无用处。

答案 1 :(得分:0)

如果在遇到i < n0for (int i = 0; i < n; i++),则程序控制不会进入for循环主体,并且不会到达return语句。 return语句是否真的应该在for循环主体中?

如果发生这种情况,则整个程序的行为为未定义。编译器警告您这一点,并且您已提高警告以使程序编译失败。

更糟糕的是,newPrefix具有自动存储期限。您正在返回一个指向它的指针,并且该指针在函数调用程序中无效。这是未定义的行为