如何在C语言中将字符指针数组传递给函数?

4

I have the following code:

int main(){
    char **array;
    char a[5];
    int n = 5;

    array = malloc(n *sizeof *array);

    /*Some code to assign array values*/

    test(a, array);

    return 0;
}

int test(char s1, char **s2){
    if(strcmp(s1, s2[0]) != 0)
        return 1;

    return 0;
}

我正试图将char和char指针数组传递给一个函数,但上面的代码导致以下错误和警告:
temp.c:在函数'main'中:
temp.c:6:5: 警告:隐式声明函数‘malloc’[-Wimplicit-function-declaration]
temp.c:6:13: 警告:不兼容的内置函数‘malloc’的隐式声明[默认情况下启用]
temp.c:10:5: 警告:隐式声明函数‘test’[-Wimplicit-function-declaration]
temp.c:在顶层:
temp.c:15:5: 错误:‘test’的类型冲突
temp.c:15:1: 注意:具有默认提升的参数类型不能匹配空参数名列表声明
temp.c:10:5: 注意:之前的‘test’的隐式声明在这里
temp.c:在函数'test'中:
temp.c:16:5: 警告:隐式声明函数‘strcmp’[-Wimplicit-function-declaration]
我试图理解问题出在哪里。

2
s1 只是一个单个字符。test 的原型应该是 int test(char* s1, char **s2) - eckes
始终包含错误——它们很重要,如果我们能向您解释它们,那么您将能够自己改进未来的代码。 - Zeta
使用gcc编译时加上-Wall --Werror参数,将所有警告视为错误。这样可以在这种情况下捕获错误。 - ugoren
4个回答

7
首先,您应该包含必要的头文件。对于strcmp,您需要<string.h>,对于malloc,您需要<malloc.h>。此外,您至少需要在主函数之前声明test。如果您这样做,您将会注意到以下错误:
temp.c: In function ‘test’:
temp.c:20:5: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast [enabled by default]
/usr/include/string.h:143:12: note: expected ‘const char *’ but argument is of type ‘char’
这表明test()应该有一个char *作为第一个参数。总的来说,您的代码应该像这样:
#include <string.h>      /* for strcmp */
#include <malloc.h>      /* for malloc */

int test(char*,char**);  /* added declaration */    

int main(){
    char **array;
    char a[5];
    int n = 5;

    array = malloc(sizeof(*array));
    array[0] = malloc(n * sizeof(**array));

    /*Some code to assign array values*/

    test(a, array);

    free(*array); /* free the not longer needed memory */
    free(array);

    return 0;
}

int test(char * s1, char **s2){ /* changed to char* */
    if(strcmp(s1, s2[0]) != 0) /* have a look at the comment after the code */
        return 1;

    return 0;
}

编辑

请注意,strcmp 适用于以 null 结尾的字节数组。如果 s1s2 都不包含 null 字节,则在 test 中调用会导致分段错误:

[1]    14940 segmentation fault (core dumped)  ./a.out

请确保两者都包含空字节 '\0',或使用strncmp 并更改 test 的签名:

int test(char * s1, char **s2, unsigned count){
    if(strncmp(s1, s2[0], count) != 0)
        return 1;
    return 0;
}

/* don' forget to change the declaration to 
      int test(char*,char**,unsigned)
   and call it with test(a,array,min(sizeof(a),n))
*/

你的内存分配错误。 array 是一个 char**。你为 *array 分配了内存,它本身是一个 char*。你从未为这个特定的指针分配内存,你漏掉了 array[0] = malloc(n*sizeof(**array)):

array = malloc(sizeof(*array));
*array = malloc(n * sizeof(**array));

第一个回答中有free()函数。 - Shark
@Shark:谢谢,你的评论让我意识到代码中仍然存在所有的分段错误 ^^"。 - Zeta

3

错误 1

temp.c:6:13: warning: incompatible implicit declaration of 
built-in function ‘malloc’ [enabled by default]

您是不是想表达这个意思?

array = malloc(n * sizeof(*array));

Error 2

temp.c:15:5: error: conflicting types for ‘test’
temp.c:15:1: note: an argument type that has a default promotion can’t 
             match an empty     parameter name list declaration
temp.c:10:5: note: previous implicit declaration of ‘test’ was here

您正在传递数组 a 的第一个元素的地址:

 test(a, array);

因此,该函数签名应该是:
int test(char* s1, char** s2)

3

您有几个问题。首先,原型是错误的。当传递给函数时,a 的数据类型会衰减为 char 指针,因此您需要:

int test (char* s1, char** s2) { ... }

然而,即使你修复了这个问题,当你第一次使用test声明时,它仍然不在作用域内。你应该提供一个原型:
int test (char* s1, char** s2);

main函数之前定义函数,或将整个函数定义移到main函数之前。此外,不要忘记#include头文件string.hstdlib.h,以使strcmpmalloc的原型也可用。


1
malloc.hstdlib.h是可移植的。 - md5

1

当您将char数组传递给函数时,参数会衰减为指针。请将您的函数参数更改为

 int test(char* s1, char **s2);
              ^
              ^ 

而且你的代码至少应该能够编译通过


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接