c语言。返回函数的类型

时间:2010-07-16 14:17:00

标签: c

?? fun()
{
   int a[3]={3,3,4};
   return &a; 
}

什么是兼容的返回类型。这里指针指向3个整数的数组,而不仅仅是指向整数数组的指针。 目标是返回一个指向3个整数数组的指针。

11 个答案:

答案 0 :(得分:14)

首先,确实应该返回本地变量的地址。当函数退出时,数组a将被销毁。

至于您的问题,&a的类型为int (*)[]

答案 1 :(得分:5)

不要这样做。

您正在返回指向局部变量的指针。当函数返回时,该指针指向一个不再有效的位置,因此这个练习毫无意义。 返回类型虽然是int (*)[3],但是当你将它用作函数的返回类型时,原型将是int (*fun(void))[3](呃,eew)

<强>然而

如果a是静态的,您可以

int (*fun(void))[3]
{ 
   static int a[3]={3,3,4}; 
   return &a;
}

返回一个指向数组中第一个元素的指针更为常见 - 尽管你必须在调用者中“知道”你可以访问3并且只能访问该指针的3个元素。

int *fun(void)
{ 
   static int a[3]={3,3,4}; 
   return &a[0]; // or just return a;
}

由于a在这些情况下是静态的,因此您必须担心reentrancy

实现相同目标的两种常见方法:

通过参数传入数组并将其分配给调用者:

void fun(int *a)
{ 
       a[0] = 3;
       a[1] = 3;
       a[2] = 4;

}

称之为:

int a[3];
fun(a);

动态分配内存:

int *fun(void) 
{
  int *a = malloc(3*sizeof *a);
  if(a) {
     a[0] = 3;
     a[1] = 3;
     a[2] = 4;
   }
   return a;
}

称之为:

int *a;
a = fun();
if(a) {
  ///use a
  free(a); // remember to free it when done
} else {
  //out of memory
}

答案 2 :(得分:4)

其他人建议的返回类型不是int*int**。返回类型是指向数组的指针。例如:

// we'll use a typedef so we can keep our sanity:
typedef int(*int3arrayptr)[3];

int3arrayptr fun()
{
    int a[3]={3,3,4};
    return &a; 
}

可以返回指向局部变量的指针时,在函数返回后不能使用这样的指针,因此不能使用fun()的返回值。

答案 3 :(得分:3)

类型为int **

但是你的代码错了,因为你的表在堆栈上。 当从函数返回时,返回堆栈中元素的指针使得引用指向无处。

答案 4 :(得分:1)

不要犯错误。一旦fun()失去范围,它的所有局部变量也会失效。

答案 5 :(得分:1)

无法从函数返回局部变量的地址。 本地变量放在堆栈中

答案 6 :(得分:1)

a是一个局部变量。不要返回指向它的指针。

回到这一点。这是在C:

中定义指向数组大小3的类型的方法
int a[3] = { 1, 2, 3 };

typedef int (*p_arr_3)[3];   

p_arr_3 fun() { return &a; }

答案 7 :(得分:0)

如果要返回指向数组的指针,请不要返回局部变量的地址。你在这里返回的是int**。你想要做的是分配一个新的int数组,并返回int*。你想要的可能是:

int* fun()
{
    int* a = malloc(sizeof(int) * 3);
    a[0] = 3;
    a[1] = 3;
    a[2] = 4;
    return a;
}

然后,您需要确保稍后释放已分配的数组。

答案 8 :(得分:0)

您的函数的返回类型为int *,您可以这样称呼它:

int *array=fun();
printf("%d\n",array[0]); //print the first value in the array

虽然!请记住,此函数返回对本地创建的变量的引用。无法保证在函数调用内部和之后内存中的值是相同的。你可能想做更像这样的事情:

int *more_fun(){
  int *a=malloc(sizeof(int)*3);
  a[0]=3;
  a[1]=3;
  a[2]=4;
  return a;
}

称之为:

int *array=more_fun();
printf("%d\n",array[0]); //print the first value in the array

但是当你完成后,请确保free(array)以免泄漏任何记忆。

答案 9 :(得分:0)

如果您要返回a,则返回类型为int *。我不完全确定在这种情况下&a意味着什么,我的方便参考告诉我,可以应用于数组的唯一操作是sizeof,而且我没有标准的方便。它可能被标记为非法,或者它可能只返回a的值。唯一的事是a表示的是数组,唯一像指向数组的指针是指向其第一个元素的指针。没有地址。

在C语言中,很难传递一个数组,因为数组在最轻微的挑衅下会衰减到指针。如果你需要传递一个实际的数组,最简单的方法是将它嵌入struct。包含struct的{​​{1}}可以作为常规值传递。

我假设您只是举个例子,因为您返回对局部变量的引用会导致各种不好的事情。在大多数实现中,该内存将用于下一个函数调用的其他事情,这意味着更改值将踩到谁知道什么,并且引用一个将获得谁知道什么。

答案 10 :(得分:0)

其他人已经告诉过你为什么你不应该这样写,但这是你感兴趣的类型。

鉴于声明int a[3],表达式&a的类型为int (*)[3] not int **)或“指向3的指针元素数组int“,例如

void f()
{
  int a[3] = {1,2,3};
  int (*aptr)[3] = &a;
  ...
}

并且返回该类型的函数的签名将是int (*fun())[3] {...}

另一个没有显示的选项是:

int (*fun())[3]
{
  int (*aptr)[3] = malloc(sizeof *aptr);
  if (aptr)
  {
    (*aptr)[0] = 1; // array pointer must be deferenced before applying
    (*aptr)[1] = 2; // the subscript. 
    (*aptr)[2] = 3;
  }
  return aptr;
}

虽然这不是非常有用;您通常不会看到像这样的单个固定大小数组的分配。更有用的是分配这些数组的数组:

int (*fun(size_t count))[3]
{
  int (*aptr)[3] = malloc(sizeof *aptr * count);
  if (aptr)
  {
    size_t i;
    for (i = 0; i < count; i++)
    {
      aptr[i][0] = 1; // aptr[i] implicitly dereferences aptr, so
      aptr[i][1] = 2; // there's no need for an explicit dereference
      aptr[i][2] = 3; // here.
    }
  }
  return aptr;
}

即便如此,如果某人需要分配固定大小的数组类型,他们通常会将其隐藏在typedef后面:

typedef int fixedSizeRecord[SOME_SIZE];
...
fixedSizeRecord *fun(size_t count)
{
  fixedSizeRecord *aptr = malloc(sizeof *aptr * count);
  if (aptr)
  {
      // initialize contents as necessary
      for (size_t i = 0; i < count; i++)
        for (j = 0; j < sizeof *aptr / sizeof *aptr[0]; j++)
          aptr[i][j] = ...;
  }
  return aptr;
}

抽象是的事情。

我之前已经对这个表进行了几次迭代;你可能会发现它很方便。

Declaration: T a[N];

Expression        Type        Decays To        Value
----------        ----        ---------        -----
         a        T [N]       T *              Address of first element in a
        &a        T (*)[N]    n/a              Address of a (same value as above,
                                                 but different type)
        *a        T           n/a              Same as a[0]
      a[i]        T           n/a              Value at index i
     &a[i]        T *         n/a              Address of value at index i
  sizeof a        size_t                       Total number of bytes in a
                                                 (N * sizeof T)
sizeof a / 
  sizeof *a       size_t      n/a              Number of elements in a (N)

Declaration: T a[N][M];

Expression        Type        Decays To        Value
----------        ----        ---------        -----
         a        T [N][M]    T (*)[M]         Address of first element in a[0]
        &a        T (*)[N][M] n/a              Address of a (same value as above,
                                                 but different type)
        *a        T [M]       T *              Same as a[0]
       a[i]       T [M]       T *              Address of first element in array 
                                                 at index i
      &a[i]       T (*)[M]    n/a              Address of array at index i (same 
                                                 value as above, but different 
                                                 type)
      *a[i]       T           n/a              Same as a[i][0]
    a[i][j]       T           n/a              Value at a[i][j]
   &a[i][j]       T *         n/a              Address of value at index i,j
   sizeof a       size_t      n/a              Total number of bytes in a
                                                 (N * M * sizeof T)
sizeof a /
  sizeof *a       size_t      n/a              Number of subarrays in a (N)
sizeof a[i]       size_t      n/a              Total number of bytes in a[i]
                                                 (M * sizeof T)
sizeof a[i] /
  sizeof *a[i]    size_t      n/a              Number of elements in a[i] (M)