如何在C

时间:2016-09-29 19:41:06

标签: c

我现在已经尝试了一段时间,我似乎无法实现这一点:

char** fetch  (char *lat, char*lon){
  char emps[10][50];
  //char** array = emps;
  int cnt = -1;

  while (row = mysql_fetch_row(result)) 
  { 
    char emp_det[3][20];
    char temp_emp[50] = "";
    for (int i = 0; i < 4; i++){
        strcpy(emp_det[i], row[i]);
    }

    if ( (strncmp(emp_det[1], lat, 7) == 0) && (strncmp(emp_det[2], lon, 8) == 0) ) {

        cnt++;
        for (int i = 0; i < 4; i++){
            strcat(temp_emp, emp_det[i]);
            if(i < 3) {     
                strcat(temp_emp, " ");
            }   
        }
        strcpy(emps[cnt], temp_emp);
    }
  }
}

mysql_free_result(result);
mysql_close(connection);
return array;

是的,我知道array = emps被注释掉了,但没有它注释,它告诉我指针类型是不兼容的。在我忘记提及的情况下,这是一个char **类型的函数,我希望它返回emps [10] [50]或下一个最好的东西。我怎么能这样做呢?谢谢!

5 个答案:

答案 0 :(得分:2)

类型T [N][M] 的数组表达式不会衰减到T ** - 它会衰减到T (*)[M](指向M的指针 - 元素数组)。

其次,您尝试返回函数本地数组的地址;函数退出后,emps数组不再存在,任何指向它的指针都将无效。

最好将目标数组作为参数传递给函数并让函数写入函数,而不是在函数中创建新数组并返回它。您可以动态分配数组,但之后您正在进行内存管理舞蹈,避免内存管理问题的最佳方法是避免进行内存管理。

所以你的函数定义看起来像

void fetch( char *lat, char *lon, char emps[][50], size_t rows ) { ... }

并且您的函数调用看起来像

char my_emps[10][50];
...
fetch( &lat, &lon, my_emps, 10 );

答案 1 :(得分:1)

即使您尝试演员,您尝试的也无法工作,因为您将返回本地变量的地址。当函数返回时,该变量超出范围,并且它使用的内存不再有效。试图取消引用该地址将导致未定义的行为。

您需要使用动态内存分配来创建要返回的数据结构:

char **emps;
emps = malloc(10 * sizeof(char *));
for (int i=0; i<10; i++) {
    emps[i] = malloc(50);
}
....
return emps;

调用函数需要free此函数创建的内存。它还需要知道已完成了多少分配,因此它知道调用free的次数。

答案 2 :(得分:1)

如果您找到了将char emps[10][50];投射到char *char **

的方法
  • 您无法正确映射数据(维度等)。多维char数组不是char **。它们只是通过索引计算来连续存储。更适合char * BTW
  • 但最大的问题是emps将超出范围,并且自动内存将被重新分配给其他变量,从而破坏数据。

但是,如果您的尺寸确实已修复,那么可以采用这种方法:

您可以创建一个以char[10][50]作为输入/输出参数的函数(您不能返回数组,编译器不允许,您可以返回包含数组的结构,但这不会有效)

示例:

void myfunc(char emp[10][50])
{
   emp[4][5] = 'a';  // update emp in the function

}

int main()
{
   char x[10][50];
   myfunc(x);
   // ...
}

main程序负责x的内存,该内存可以修改为myfunc例程:它安全快速(无内存副本)

良好做法:定义类似typedef char matrix10_50[10][50];的类型,使声明更符合逻辑。

这里的主要缺点是尺寸是固定的。如果您想将myfunc用于其他维度集,则必须复制/粘贴它或使用宏来定义它们(就像穷人的模板一样)。

编辑

一个好的评论表明一些编译器支持变量数组大小。 因此,您可以将尺寸与无约束数组一起传递:

void myfunc(int rows, int cols, char emp[rows][cols])

经过测试,可以使用gcc 4.9(也可能在早期版本上)仅限于C代码,而不是C ++,而不适用于包含普通C的.cpp文件(但仍然很麻烦) malloc/free来电)

答案 3 :(得分:0)

为了理解为什么不能这样做,你需要了解矩阵在C中是如何工作的。

一个矩阵,让我们说你的char [10] [50]是一个连续的存储块,能够存储10 * 50 = 500个字符(想象一个500个元素的数组)。当你访问emps [i] [j]时,它访问那个&#34;数组&#34;中索引50 * i + j的元素。 (选择一张纸和一支笔来了解原因)。问题是该公式中的50是矩阵中的列数,这在编译时从数据类型本身就已知。当你有一个char **时,编译器无法知道如何访问矩阵中的随机元素。

构建矩阵以使其成为char **的一种方法是创建一个指向char的指针数组,然后分配每个指针:

char **emps = malloc(10 * sizeof(char*)); // create an array of 10  pointers to char
for (int i = 0; i < 10; i++)
    emps[i] = malloc(50 * sizeof(char)); // create 10 arrays of 50 chars each

关键是,您不能以将数组转换为指针的方式将矩阵转换为双指针。

答案 4 :(得分:-1)

另一个问题:将二维矩阵作为'char **'返回只有在使用一个指针数组实现矩阵时才有意义,每个指针指向一个字符数组。如前所述,C中的2D矩阵只是一个扁平的字符数组。你可以返回的最多是指向[0] [0]条目的指针,一个'char *'。间接数量不匹配。