[英]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.