在我写的cmets中:
这种“不使用最合适的工具来解决”的问题对你来说应该是一个危险信号;你的资源,无论是什么,都在教你以不恰当的方式解决问题。为什么,在现实世界中,没有人在这里使用 C 语言中的循环?或者,如果作者想教授函数式编程,他们为什么要使用非函数式语言,比如 C? 买一本更好的书!
尽管如此,我发现自己在这里提供了一个答案......
首先,从技术上讲,它们都是循环!我收集当你声明你不能使用任何循环时,你实际上指的是过程循环(即从goto、while、@构建的循环987654323@ 或 for),而不是 功能循环(由递归函数应用程序构建)。从技术上讲,它们都是循环,并且由于 C 是一种过程语言您应该使用过程循环。不过……
有一个模式!只需通过观察和重现一个模式,程序循环就可以转换为功能循环。也就是说,每个程序循环都有一个等效的功能循环,它们最终看起来都非常相似。寻找下面的模式。
这是一个包含基本过程循环的函数:
void procedural_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) {
while (source[source_position] != '\0') {
source_position++;
}
}
...这里是一个功能循环:
void functional_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) {
if (source[source_position] != '\0') {
source_position++;
functional_loop_on_str(source, source_position, dest, dest_position);
}
}
这两段代码看起来很相似,不是吗?基于此观察,任何程序循环都可以简单地转换为功能等价物;您要做的就是添加填充循环的额外代码。作为练习,请考虑隔离此代码中相同的部分。它们通常在两段代码中位于同一个位置;他们不难找到!事实上,这些差异并列如下:
while ... if ...
functional_loop_on_str...
当需要回溯时,唯一的困难就出现了,这与这个问题无关。因此,您应该能够编写过程版本并将其轻松转换为功能版本。请允许我开始:
void procedural_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) {
while (source[source_position] != '\0') {
int value, nbytes, success = sscanf(source + source_position, "%d%n", &value, &nbytes);
if (!success) { nbytes = 1; }
else { /* XXX: You do this part!
* You need to do something with value, dest and dest_position */
}
source_position += nbytes;
}
}
...这里通过复制模式将其转换为我们的功能版本:
void functional_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) {
if (source[source_position] != '\0') {
int value, nbytes, success = sscanf(source + source_position, "%d%n", &value, &nbytes);
if (!success) { nbytes = 1; }
else { /* XXX: You do this part!
* You need to do something with value, dest and dest_position */
}
source_position += nbytes;
functional_loop_on_str(source, source_position, dest, dest_position)
}
}
请注意这两个示例之间的实际变化很小;大部分模式仍然存在!还记得上面的练习吗?好吧,你可以在这里做同样的事情,发现从程序性转换为功能性时,在同一个地方进行了相同的更改。
我认为,如果您阅读了一本(更好的)关于函数式编程的书和一本(更好的)关于 C 编程的书,或者甚至自己创建了这些基本示例来观察该模式,那么我认为这种模式对您来说是显而易见的。尽管如此,我坚持我的信念:
- 您不应该在 C 或任何过程语言中使用函数循环,尤其是不是 C;如果 C 是为日常功能循环而设计的,那么标准中就会有优化保证。如果您的指南另有说明,请考虑选择新指南,例如由 C Kernighan & Richie 的创始人所写的带有巨大蓝色“C”的书(选择第二版)。我会让你找到那个。
- 您不应该使用过程语言来研究功能元素。这是不言而喻的。考虑方案;有一本关于 Scheme 的非常好的“向导书”!
不管怎样,看来你需要一本更好的书!