首页
/
每日頭條
/
圖文
/
二維數組做形參可以不設置大小嗎
二維數組做形參可以不設置大小嗎
更新时间:2025-12-14 01:26:44

二維數組做形參可以不設置大小嗎?最近碰到一個問題點,這裡跟大家分享一下有一個二維數組,我想把它傳給一個函數于是我把函數接口定義出來了,如下:,我來為大家科普一下關于二維數組做形參可以不設置大小嗎?下面希望有你要的答案,我們一起來看看吧!

二維數組做形參可以不設置大小嗎(二維數組如何當形參)1

二維數組做形參可以不設置大小嗎

抛出問題

最近碰到一個問題點,這裡跟大家分享一下。有一個二維數組,我想把它傳給一個函數。于是我把函數接口定義出來了,如下:

int array[2][3] = {1,2,3,4,5,6}; void fun(int **array) { array[0][0] = 5; }

當我試圖直接把數組名傳給函數時候,fun(array)編譯會報錯,大概意思就是類型不匹配。既然類型不匹配,那我就直接強轉成你所需要的類型,于是我又做了調整,fun((int **)array),這下确實不報錯了。但是此時我還沒意識到問題的嚴重性。不出意外的情況下意外還是發生了,隻要進入到這個函數後,程序就挂了。那你知道是什麼原因嗎?如果不清楚就往下看吧...

指針

先從指針說起,指針是一個特殊的變量, 它裡面存儲的數值被解釋成為内存裡的一個地址。要搞清一個指針需要搞清指針的四方面的内容:指針的類型、 指針所指向的類型 、 指針的值或者叫指針所指向的内存區、 指針本身所占據的内存區。

指針的類型

隻要把指針聲明語句裡的指針名字去掉,剩下的部分就是這個指針的類型。例如:

int*ptr; //指針的類型是 int* char*ptr; //指針的類型是 char* int**ptr; //指針的類型是 int** int(*ptr)[3]; //指針的類型是 int(*)[3]

指針所指向的類型

隻須把指針聲明語句中的指針名字和名字左邊的指針聲明符*去掉, 剩下的就是指針所指向的類型。例如:

int*ptr; //指針所指向的類型是 int char*ptr; //指針所指向的的類型是 char int**ptr; //指針所指向的的類型是 int* int(*ptr)[3]; //指針所指向的的類型是 int()[3]

指針的值

在32位程序裡,所有類型的指針的值都是一個32位整數,因為32位程序裡内存地址全都是32位長。

指針本身所占用的内存大小

意思是指針本身占了多大的内存,在32位平台裡,指針本身占據了4個字節的長度。可以使用sizeof(指針的類型)測試。

一維數組

對于一個一維數組int array[10],數組名代表一個常量地址,該地址指向第一個元素。以下兩種情況數組名不能當指針使用。

&

對數組名取址,int *p_array = &array,&這個運算符也很有講究的,暫時不多說了。

sizeof

sizeof(array)計算的是整個數組在内存中所占用的空間。

二維數組

二維數組本質上是以數組作為數組元素的數組,即“數組的數組”。假設我們定義了一個二維數組int array[2][3] = {1,2,3,4,5,6}。

網上有很多地方都再說數組名array和array[0]、&array[0]以及&array[0][0]是等效的。那我們代碼測試一下。

printf("%#x,%#x,%#x,%#x\r\n",array,array[0],&array[0],&array[0][0]); Terminal: 0x404008,0x404008,0x404008,0x404008

因為這幾種寫法輸出地址都是相同的,所以有的同學自然就認為這幾種寫法就是一樣的。雖然地址相同,但是實際意義是有區别的,我們繼續看下面的代碼。

//這裡重新定義了指針變量,能夠方便的知道右值得類型 int *p_array1 = array[0]; int *p_array2 = &array[0][0]; int (*p_array3)[3] = &array[0]; int (*p_array4)[3] = array; printf("%#X,%#X,%#X,%#X,%#X\r\n",array, p_array1, p_array2, p_array3, p_array4); Terminal: 0X404008,0X40400C,0X40400C,0X404014,0X404014

根據以上實驗分析能夠看出:array[0]與&array[0][0]指針類型相同,都是int *,地址存放的是int數據,當指針自增1時地址都偏移了一個int類型的大小。

&array[0]與array指針類型相同,都是int (*)[3],首先它是一個數組指針,這個指針指向一個數組,數組中數據的類型為int型。當指針自增1時地址都偏移了一個數組的長度(即3個int數據的大小)。

所以說array隻和&array[0]真正意義等效。那怎麼去理解這幾種表達呢 ?

表示

含義

array

是一個數組指針,類型為int (*)[3]。指向二維數組中第一個元素(元素是一維數組),指針所指向的内存大小為一維數組的長度

array[0]

是一個指針,類型為int *。就相當于一個一維數組名,指向一維數組中第一個元素的地址,指針所指向的内存大小為一個數據長度

&array[0]

是一個數組指針,類型為int (*)[3]。相當于對一維數組取地址。指針所指向的内存大小為一維數組的長度

&array[0][0]

是一個指針,類型為int *,是對二維數組中第一個數據取地址,注意是數據不是元素,指針所指向的内存大小為一個數據長度

如以上能夠理解清楚,那麼文中的問題應該就能夠自己分析清楚了。

二級指針

先定義一個二級指針int **p,首先p是一個指針,在這個地址中存放的數據是指向一個整形數據的地址。

問題解答

接着看文章中的問題,把一個二維數組強轉成二級指針傳給了函數。注意二維數組名的類型是一個數組指針和二級指針完全不是一個東西。那麼會出現什麼問題呢?

int array[2][3] = {1,2,3,4,5,6}; int main(int argc ,char **argv) { int **p_data = (int **)array; printf("%#x, %d\r\n", p_data, *p_data); } Terminal: 0x404008, 1

地址

數據

0x404008

1

0x40400C

2

0x404010

3

0x404014

4

0x404018

5

0x40401C

6

看上面的例子,array的地址為0x404008,當把一個二維數組強轉成二級指針的時候。p_data地址中存放的數據為1,因為二維數據中第一個數據就是1。根據二級指針的定義,這個數據1又會當成一個地址,該地址指向的内存才是最終的數據。

但是呢,這個地址1其實是個數據,并不是真正的地址。如果訪問地址1中的數據,就屬于非法訪問地址了,可能會進入異常。

二維數據當函數入參

通過以上學習我們已經知道二維數組名就是一個數組指針,我們函數就可以像下面這樣聲明。

void fun(int array[][3], int row); void fun(int (*p_array)[3], int row); void fun(int row, int column, int array[row][column]);

實參與入參

最後在看下,應該如何定義與實參相對應地形參的數據類型。

含義

實參

形參

二維數組(數組的數組)

int array[4][6]

int (*array)[6]

指針數組(數組中的數據是指針)

int *array[6]

int **array

數組指針(指向數組的指針)

int (*array)[6]

int (*array)[6]

二級指針(指針的指針)

char **array

char **array

,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
道德經第三十二章個人理解(道德經二十五章)
道德經第三十二章個人理解(道德經二十五章)
  今天我們來學習道德經的第二十五章。原文:   有物混成,先天地生。寂兮寥(liao二聲)兮,獨立而不改,周行而不殆,可以為天地母。吾不知其名,強字之曰道,強為之名曰大。大曰逝,逝曰遠,遠曰反。   故道大,天大,地大,人亦大。域中有四大,而人居其一焉。人法地,地法天,天法道,道法自然。   為了節約時間,原文我就不念了,接下來直接翻譯一下這章:     ...
2025-12-14
奔跑吧第一季陣容官宣(奔跑吧全新陣容合體亮相春推會)
奔跑吧第一季陣容官宣(奔跑吧全新陣容合體亮相春推會)
  3月28日,全新一季《奔跑吧》家族的七位成員李晨、Angelababy、鄭恺、朱亞文、王彥霖、黃旭熙、宋雨琦合體亮相浙江衛視春推會,兄弟團相聚一堂,其樂融融、笑聲不停。現場還有《王牌對王牌》家族沈騰、賈玲、華晨宇、關曉彤歡樂集結,更有《中國好聲音》全新導師王力宏驚喜出席,浙江衛視新年的亮相可謂是全員出動大陣仗了。      超長花絮引爆全場,李晨撕名牌以...
2025-12-14
楊潔為何後悔拍西遊(三次邀請王伯昭)
楊潔為何後悔拍西遊(三次邀請王伯昭)
  在82版西遊記中,要說誰是最貴的演員,估計很多人會說是六小齡童,也有人可能會說是馬蘭,也就是飾演唐僧母親的演員,當年千裡送馬蘭的故事,還不時被人說起,在西遊記裡最貴的演員其實是飾演小白龍的演員王伯昭,總共出演了3集,片酬卻高達1500,當年劇組經費緊張,各種省吃儉用,按照楊潔導演的性格,肯定是不會花這麼多錢請王伯昭的,那到底是誰請的呢?      當年在...
2025-12-14
曆史上洛陽地區下轄多少縣(1952年河南洛陽下轄11個縣)
曆史上洛陽地區下轄多少縣(1952年河南洛陽下轄11個縣)
  河南洛陽是我國的四大古都之一,建都時間算的話是我國的第一大古都,長期是河南府的駐地。其實河南省名稱的确定就是舊來自于洛陽河南府,不過奇怪的是洛陽從來沒有做過河南省的省會,可能跟地理位置有關系,實在太偏西了。發展到如今洛陽僅下轄7個縣,不過仍然是中西部地區非省會地級市 GDP第1名,而在1952年河南洛陽下轄11個縣,廣大的豫西地區都是洛陽專區管轄,曾經鼎...
2025-12-14
元啟為什麼是白絕兒子(千古玦塵後池生了個兒子)
元啟為什麼是白絕兒子(千古玦塵後池生了個兒子)
  由周冬雨、許凱領銜主演,張嘉倪、劉學義等主演的古裝玄幻仙俠劇《千古玦塵》正在熱播當中。   現如今,該劇已經開啟了超前點播,正片直接從原本的第二十八集更新到了三十八集,預告片也順帶着更新到了第四十四集。      後池生了個兒子根據四十三集和四十四集的預告片來分析,後池已經覺醒為主神上古。   她身為後池時所生的兒子也已經長大。   不似四十二集的預告片...
2025-12-14
Copyright 2023-2025 - www.tftnews.com All Rights Reserved