在C语言中没有循环是否可以打印数组?

p1iqtdky  于 2023-01-08  发布在  其他
关注(0)|答案(5)|浏览(206)

例如,在Python中,如果我们把一个列表当作一个数组,它会直接打印整个数组,只需要一行代码,有没有办法在C语言中实现同样的效果?

uurity8g

uurity8g1#

简短回答

没有

表单上几乎所有问题的简短答案 “你能像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 ----|

注意,我调换了gotos的位置,所以这个“循环”没有正确嵌套。没有内部循环和外部循环。这就是所谓的“意大利面代码”,也是goto不受欢迎的原因,因为它使代码很难理解。但当它是编译器编写的汇编时,这并不重要。
那么这个代码片段算不算一个循环,虽然很复杂?TBH,我不确定。但是我知道递归和常规迭代是 * 同样有表达力的 *,这意味着 * 没有什么东西你可以递归计算,你不能迭代计算,反之亦然 *。阅读here了解更多信息。
有些东西用递归风格写起来会容易得多,例如阿克曼函数:How to rewrite Ackermann function in non-recursive style?

xghobddn

xghobddn2#

你可以使用递归-没有循环。

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

idfiyjo8

idfiyjo83#

是的,我们可以。如果数组大小是固定的,比如说数组的大小是6。那么你可以打印这些值,比如printf(a[0])到printf(a[5])。如果你给用户给予了“n”的值(这里n是数组的大小),那么你不知道用户会给什么值。所以在这种情况下,你需要循环来打印数组中的值。

mepcadol

mepcadol4#

如果是字符数组,则如下所示:

char a[] = "abcdefghi";
printf("%.3s", a); // prints -> abc

如果你想打印可变数量的字符:

char a[] = "abcdefghi";
char fmt[128];
int n = 3;
sprintf(fmt, "%%.%ds", n);
printf(fmt, a); // prints -> abc

用于不以\0结尾的字符数组

vbkedwbf

vbkedwbf5#

是的,它可以打印一个没有循环的数组,你只需要使用后藤statemenet来创建一个循环,并检查if条件

my:

   if(i<n)
   {
    scanf("%d",&arr[i]);
    i++;
    goto my;
}
else{
    printf(" ");
}
j=0;
to:
    
if(j<n)
{
    printf("%d ",arr[j]);
    j++;
    goto to;
}
else{
    printf(" ");
}

相关问题