我是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循环的版本无法编译的任何想法?
答案 0 :(得分:1)
如果n <= 0
,则将永远不会进入for
循环,因此,将永远不会到达循环主体中的return
语句。由于循环后没有return
语句,因此编译器会抱怨(正确的是)。
那是说:您确定在循环体内有无条件的return
语句不是错误吗?这使循环变得毫无用处。
答案 1 :(得分:0)
如果在遇到i < n
时0
是for (int i = 0; i < n; i++)
,则程序控制不会进入for
循环主体,并且不会到达return
语句。 return
语句是否真的应该在for
循环主体中?
如果发生这种情况,则整个程序的行为为未定义。编译器警告您这一点,并且您已提高警告以使程序编译失败。
更糟糕的是,newPrefix
具有自动存储期限。您正在返回一个指向它的指针,并且该指针在函数调用程序中无效。这是未定义的行为。