【问题标题】:Pass a char pointer array to a function in C?将char指针数组传递给C中的函数?
【发布时间】:2012-07-28 23:04:11
【问题描述】:

我有以下代码:

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:警告:函数“测试”的隐式声明 [-Wimplicit-function-declaration]
temp.c:在顶层:
temp.c:15:5:错误:“测试”的类型冲突
temp.c:15:1:注意:具有默认提升的参数类型不能匹配空参数名称列表声明
temp.c:10:5:注意:先前的“测试”隐式声明在这里
temp.c:在函数“测试”中:
temp.c:16:5:警告:函数‘strcmp’的隐式声明 [-Wimplicit-function-declaration]

我正在尝试了解问题所在。

【问题讨论】:

  • s1 只是一个字符。 test的原型应该是int test(char* s1, char **s2)
  • 始终包含错误 - 它们很重要,如果我们也可以向您解释它们,那么您将能够自己改进未来的代码。
  • 编译所有警告并将它们视为错误(Witg gcc,-Wall --Werror)。在这种情况下它会捕获错误。

标签: c arrays pointers char


【解决方案1】:

首先,您应该包含必要的头文件。对于strcmp,您需要<string.h>,对于malloc <malloc.h>。此外,您至少需要声明 test before main。如果您这样做,您会注意到以下错误:

temp.c:在函数“测试”中:
temp.c:20:5: 警告:传递“strcmp”的参数 1 使指针从整数不进行强制转换 [默认启用]
/usr/include/string.h:143:12:注意:预期为“const char *”,但参数的类型为“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 适用于以空字符结尾的字节字符串。如果s1s2 均不包含空字节,则test 中的调用将导致分段错误:

[1] 14940 分段错误(核心转储)./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))
*/

你的内存分配也是错误的。 arraychar**。您为*array 分配内存,它本身就是char*。你永远不会为这个特定的指针分配内存,你错过了array[0] = malloc(n*sizeof(**array))

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

【讨论】:

  • 第一个答案是 free() :)
  • @Shark:谢谢,您的评论让我意识到代码中仍然存在的所有分段错误^^"。
【解决方案2】:

错误 1

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

你是这个意思吗?

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

错误 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 的原型也可用。

    【讨论】:

    • malloc.h ? stdlib.h 是可移植的。
    【解决方案4】:

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

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

    你的代码至少应该可以编译

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-02
      • 2016-03-27
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 2021-09-07
      • 2015-03-17
      相关资源
      最近更新 更多