使用C返回数组,采用不同的方法

时间:2011-04-24 15:37:46

标签: c arrays pointers

我之前已经问过这个问题:Experimenting with pointers of arrays in C关于传递指向函数的指针和修改函数中的现有数组,作为将数组“返回”main()的方法。我只留下一个问题,这两个代码块之间有什么区别?

// #includes

int ***myfunc(int*** );

int main() 
{
    int a***;
    //allocate memory for array 'a'
    a = myfunc(a);

    // display all contents of array 'a'

    return 0;
}

OR

// #includes

void myfunc(int*** );

int main() 
{
    int a***;
    //allocate memory for array 'a'
    myfunc(a);

    // display all contents of array 'a'

    return 0;
}

两个函数都将修改数组,当displaying all contents of a时,内容将相同。

我希望这不会令人困惑,我想如果需要我可以详细说明。

重要的EDITTTTTTTT

下面是两个工作示例(据我所知):

#include "stdlib.h"
#include "stdio.h"


void myfunc(int** );

int main() {

  int **a,i, j;

  a = (int**) calloc(10,sizeof(int*));
  for (i=0; i<10; i++)
    a[i] = (int*) calloc(10, sizeof(int));

  myfunc(a);

  for (i=0; i<10; i++) {
    for (j=0; j<10; j++)
      printf("%d ",a[i][j]);
    printf("\n");
  }

  return 0;
}


void myfunc(int** a) {

  int i, j;
  for (i=0; i<10; i++)
    for (j=0; j<10; j++)
      a[i][j] = i*j;

}

和...

#include "stdlib.h"
#include "stdio.h"

// returning arrays through functions

int **myfunc(int **b);

int main() {

  int **a,i,j;

  a = (int**) calloc(10,sizeof(int*));
  for (i=0; i<10; i++)
    a[i] = (int*) calloc(10, sizeof(int));

  a = myfunc(a);

  for (i=0; i<10; i++) {
    for (j=0; j<10; j++)
      printf("%d ",a[i][j]);
    printf("\n");
  }

  return 0;
}


int **myfunc(int **b) {

  int i, j;
  for (i=0; i<10; i++)
    for (j=0; j<10; j++)
      b[i][j] = i*j;

  return b;
}

2 个答案:

答案 0 :(得分:3)

第二个函数无法修改传递给它的指针(int***),但是当你进行分配时,你将获得一个新的内存地址。这个新地址将被分配到 myfunc内指针的本地副本,但它永远不会到达main

这样做的后果是:

  • main
  • 中使用无效指针
  • 泄漏myfunc内分配的内存。

你可以通过指针指针来缓解这个问题(哇!):

// #includes

void myfunc(int****);

int main() 
{
    int ***a; // <-- note: you had a typo here, originally!

    //allocate memory for array 'a'
    myfunc(&a); // <-- pass pointer by pointer

    // display all contents of array 'a'

    return 0;
}

并确保myfunc对此有所了解。

使用typedef

可以更清楚地了解上述代码
// #includes
typedef int*** Ptr;

void myfunc(Ptr*);

int main() 
{
    Ptr a;

    //allocate memory for array 'a'
    myfunc(&a); // <-- pass pointer by pointer

    // display all contents of array 'a'

    return 0;
}

尽管如此,你的第一种方法更清晰,避免了对这种废话的任何需要。它只返回指针的新值,然后您可以根据需要分配和使用它。


修改 (对重要问题编辑的回复)

我已经明白内存分配是在myfunc完成的;我现在看到的情况并非如此。

因此,你可以使用你列出的两种方法中的任何一种(或者我在上面描述的第三种方法);而且,坦率地说,我不明白你为什么要打扰第一个,因为你不会修改myfunc内的指针。

答案 1 :(得分:0)

您想要修改a的值,因此您必须传递指向它的指针,而不是值本身:

myfunc(&a); // as opposed to myfunc(a);

如果要返回指向的事物的指针以及修改输入参数,那么在返回类型中使用一个较少级别的间接:

int **myfunc(int ***a) { ... }

所以main中的调用看起来像

int **a, **b;

b = myfunc(&a);