有多少种方法可以将char数组传递给C函数?

时间:2015-09-03 13:45:06

标签: c arrays pointers argument-passing

  • background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wgUEhgsb9YM9wAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAADUlEQVQI12NgYGBgAAAABQABXvMqOgAAAABJRU5ErkJggg==);
  • foo(char *s)
  • foo(char *s[ ])

所有这些有什么不同?

有没有什么方法可以修改作为参数传递的数组元素,就像我们使用foo(char s[ ])int传递float&一样实际的参数被修改了吗?

4 个答案:

答案 0 :(得分:4)

在C中无法按值传递数组。您列出的每个工作解决方案(不幸的是排除了#2)不仅会让您,而且会强制您修改原始数组。

由于参数衰减,foo(char* s)foo(char s[])完全相同。在这两种情况下,都使用其名称传递数组:

char array[4];
foo(array); // regardless of whether foo accepts a char* or a char[]

在这两种情况下,数组都被转换为指向其第一个元素的指针。

指针到阵列解决方案不太常见。它需要以这种方式进行原型化(注意*s周围的括号):

void foo(char (*s)[]);

没有括号,你需要一个char指针数组。

在这种情况下,要调用该函数,需要传递数组的地址:

foo(&array);

每次要访问数组元素时,还需要从foo取消引用指针:

void foo(char (*s)[])
{
    char c = (*s)[3];
}

就像那样,它不是特别方便。但是,唯一允许您指定数组长度的形式,您可能会发现它很有用。这是我个人的最爱之一。

void foo(char (*s)[4]);

如果您尝试传递的数组没有正好4个字符,编译器将发出警告。此外,sizeof仍然按预期工作。 (明显的缺点是数组必须具有确切的元素数。)

答案 1 :(得分:2)

场景:您以数组作为参数调用该函数。

在那种情况下,

 foo(char *s)

 foo(char s[])

被视为等同于。他们都期望用char数组调用。

OTOH,foo(char *s[ ]),不同,因为它采用char *数组的地址。

答案 2 :(得分:1)

  • foo(char *s)非常简单,它只是一个指针,可能是指向数组第一个元素的指针。

  • foo(char s[])是char数组的声明,但由于C标准中的(愚蠢)规则,它被转换为指向char的指针。同样,如果声明任何数组大小,仍然会获得指向char的指针。

    提到的规则可以在C11 6.7.6.3函数声明符中找到:

      

    参数声明为''数组类型''应调整为   ''指向类型''的合格指针

    如果这个奇怪的,令人困惑的,并且会成为阵列的话,那可能会好得多。语法被完全禁止,因为它是100%多余的,并且没有任何其他目的,但是混淆了尝试加入" C俱乐部的初学者"。但那时C从来就不是一种理性的语言......

    有人会说,基本原理是,出于性能原因,绝不允许您在C中按值传递数组。好吧,运气不好,因为尽管有这个规则,你仍然可以。

  • 你可以"破解C标准"并按值传递数组:

    typedef struct
    {
      char array[10];
    } by_val_t;
    
    foo (by_val_t arr);  // bad practice but possible
    

    现在真的没有理由为什么你想要按值传递一个数组,这是非常糟糕的程序设计,并没有任何意义。我只是在这里包含这个例子来证明6.7.6.3中的规则完全没有任何理由。

  • 您可以将数组指针作为参数传递给函数。这是事情变得先进的地方,因为这是非常模糊的,并且实际使用非常有限:

    foo(char(*s)[])
    

    如果你在这里指定一个数组大小,你实际上得到了一些类型安全性,因为编译器倾向于警告不同大小的数组指针之间的转换。

    但请注意,数组指针主要用于使C语言更加一致。你想要将一个数组指针传递给一个函数的原因很简单(here是一个有点复杂的例子,我显然找到了它的有效用法)。

答案 3 :(得分:0)

  

foo(char *s)foo(char *s[ ])foo(char s[ ]),所有这些有什么不同?

在这些foo(char *s)foo(char s[ ])中,两者都会期望char array作为参数。

异常剩下这个 - foo(char *s[ ])这将指向一个指向chars的指针数组作为参数。