在C语言中没有任何循环可以打印数组吗?
例如,在 Python 中,如果我们将列表作为数组,它会直接打印一行代码的整个数组。有没有办法,在C语言中实现同样的事情?
回答
简答
不
对表格中几乎所有问题的简短回答“你能像 Python 一样在 C 中做 X 吗?”
不
长答案
这取决于你的意思。在内部,Python 也使用循环。它只是对您隐藏,所有编程语言也是如此。如果要处理数组,通常需要在某个级别上进行循环。
因此,如果您的问题是是否有一些用于打印数组的预定义函数,那么答案是否定的,前提是该数组不是字符串。但是为此编写自定义打印功能并不困难。这是一个打印相当漂亮的示例:
void print_int_array(int *arr, size_t size) {
if (size == 0) {
printf("[]");
} else {
putchar('[');
for (int i = 0; i < size - 1; i++)
printf("%d, ", arr[i]);
printf("%d]", arr[size - 1]);
}
}
也可以使用递归,但递归基本上只是一个伪装的循环。这是上面的递归版本:
void print_int_array_rec(int *arr, size_t size) {
if (size == 0) {
putchar(']');
} else {
printf("%d", *arr);
if (size == 1)
printf(", ");
print_int_array_rec(arr + 1, size - 1);
}
}
void print_int_array(int *arr, size_t size) {
putchar('[');
print_int_array_rec(arr, size);
}
但正如我所说,它基本上只是一个伪装的循环。至少在这个简单的情况下。所有循环通常在汇编中转换为这样的:
loop_start:
// Code
if(<condition>) goto loop_start
或者使用嵌套循环:
loop_start:
// Code
loop2_start:
// Code
if(<condition>) goto loop2_start
// Code
if(<condition>) goto loop_start
通过递归,这些跳转会变得更加复杂。如果您使用复杂的递归,则跳转可能会停止正确嵌套。它可能会导致这样的事情:
loop_start:
// Code
loop2_start:
// Code
if(<condition>) goto loop_start
// Code
if(<condition>) goto loop2_start // Switched the gotos
请注意,我在 goto 上切换了位置,因此此“循环”未正确嵌套。没有内循环和外循环。这就是所谓的意大利面条式代码,其原因goto是不受欢迎的,因为它使代码很难遵循。但是它什么时候是由编译器编写的程序集并不重要。
那么这个片段是否算作一个循环,尽管是一个复杂的循环?TBH,我不确定。但我所知道的是,递归和常规迭代同样具有表现力,这意味着没有任何东西可以递归计算而不能迭代计算,反之亦然。阅读此处了解更多信息。
以递归方式编写某些事情变得容易得多。例如,阿克曼函数:如何以非递归方式重写阿克曼函数?
回答
您可以使用递归 - 没有循环。
void printarray1(int *array, size_t size, size_t pos)
{
if(pos < size) {printarray1(array, size, pos + 1); printf("%d%s", array[size - pos - 1], pos ? " ": "");}
}
void printarray(int *array, size_t size)
{
printf("[");printarray1(array, size, 0);printf("]");
}
int main(void)
{
int array[] = {1,2,3,4,5,6,7,8,9,10};
printarray(array, sizeof(array)/sizeof(array[0]));
}
https://godbolt.org/z/Y79xTG