簡體   English   中英

C語言。 函數的返回類型

[英]c language. Return type of a function

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

什么是兼容的返回類型。 這里的指針指向的是3個整數的數組,而不僅僅是指向整數數組的指針。 目的是返回一個指向3個整數的數組的指針。

首先,你真的 應該返回一個局部變量的地址。 當函數退出時,數組a將被銷毀。

至於您的問題, &a的類型為int (*)[]

不要這樣

您正在返回一個指向局部變量的指針。 當函數返回時,該指針指向不再有效的位置,因此此練習毫無意義。 返回類型本來是int (*)[3] ,但是當您將其用作函數的返回類型時,原型將是int (*fun(void))[3] (ugh,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是靜態的,因此您必須擔心重新進入

2種常見的相同方法:

通過參數傳遞數組並在調用方中分配它:

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
}

返回類型將不是其他建議的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()的返回值。

類型為int **

但是您的代碼是錯誤的,因為您的表在堆棧中。 從函數返回時,返回堆棧中元素的指針會使引用無處指向。

不要犯錯。 一旦fun()失去作用域,它的所有局部變量也將失去作用域。

局部變量的地址不能從函數返回。 局部變量放置在堆棧中

a是局部變量。 不要返回指向它的指針。

回到重點。 這是在C中定義大小為3的數組的指針的方式:

int a[3] = { 1, 2, 3 };

typedef int (*p_arr_3)[3];   

p_arr_3 fun() { return &a; }

如果要返回指向數組的指針,請不要返回局部變量的地址。 您返回的這里是int** 您要做的是分配一個新的int數組,然后返回int* 您想要的可能是這樣的:

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

然后,您需要確保稍后釋放分配的陣列。

您的函數的返回類型為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)以免泄漏任何內存。

如果要返回a ,則返回類型為int * 我不確定在這種情況下&a是什么意思,我方便的參考告訴我,可以應用於數組的唯一操作是sizeof ,而我沒有Standard的方便。 它可以被標記為非法的,或者它可能只是返回的值a a表示的唯一內容是數組,並且唯一類似於數組的指針的內容就是指向其第一個元素的指針。 沒有地址的地址。

在C語言中,很難遍歷數組,因為數組在絲毫挑釁下會衰減到指針。 如果您需要傳遞一個實際的數組,則最簡單的方法是將其嵌入struct struct含有int a[3]; 可以作為常規值傳遞。

我假設您只是舉一個例子,因為您返回對局部變量的引用會導致各種不良情況。 在大多數實現中,該內存將在下一個函數調用時用於其他用途,這意味着更改值將使誰知道什么,而引用一個值將得到誰知道。

其他人已經告訴過您為什么不應該這樣做,但是這里是您感興趣的類型。

給定一個聲明int a[3] ,表達式&a的類型為int (*)[3]不是 int ** )或“指向int的3元素數組的指針”,例如

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM