近來(lái)在寫(xiě)程序的時(shí)候遇到了一個(gè)問(wèn)題,就是傳遞一個(gè)數(shù)組指針進(jìn)入一個(gè)函數(shù)的時(shí)候,雖然指針能夠順利的傳遞,但是,我們無(wú)法求出該數(shù)組的大小。見(jiàn)下面的代碼:
#include <stdio.h>
void setNum(int *p,int a);
void setNum(int *p);

int main()


{

int a[] =
{1,2,4,5};
printf("%d\n",sizeof(a)/sizeof(a[0]));
setNum(a);
}

void setNum(int *p,int a)


{
*p = a;
}

void setNum(int *p)


{

int Num = sizeof(p)/sizeof(p[0]);
printf("%d\n",Num);
}
結(jié)果是,輸出分別是4和1.
原因分析:
1.對(duì)于第一個(gè)輸出,由于在main函數(shù)中定義的為數(shù)組,所以可以直接利用sizeof函數(shù)來(lái)求出a數(shù)組的長(zhǎng)度。
2.對(duì)于傳遞參數(shù)類(lèi)型,比如上面的setNum函數(shù)(未傳遞個(gè)數(shù)版本),此時(shí),調(diào)用該函數(shù)的時(shí)候,a退化為一個(gè)普通的指針,也就是說(shuō),此時(shí)sizeof(p)求出來(lái)的就是一個(gè)指針的大小,除以int的大小,恰好為1.
啟示:
C語(yǔ)言中,不能夠根據(jù)一個(gè)數(shù)組指針就求出來(lái)任意一個(gè)數(shù)組的大小。解決辦法就是傳第一個(gè)參數(shù)進(jìn)來(lái),指定大小。
ps:參考資料(詳實(shí)):
http://topic.csdn.net/t/20060205/18/4540750.html摘錄:
> 如果作為函數(shù)的參數(shù)是沒(méi)法求的,
> 但這樣是可以的:
>
> #define LENGTH(s) (sizeof(s) / sizeof(int))
>
> int s[12];
> int length = LENGTH(s);
==================================================
這樣的方法只能用于數(shù)組變量的數(shù)組名,對(duì)于指向數(shù)組的指針,以及作為參數(shù)的數(shù)組名都是沒(méi)有效果的,上面已經(jīng)有人解釋了
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
不可能有辦法的。
當(dāng)你定義一個(gè)數(shù)組的時(shí)候:
int a[] = {1, 2, 3}; // 實(shí)際上被編譯為 int a[3] = {1,2,3}
數(shù)組名代表的是數(shù)組的地址。注意 —— 你絕對(duì)沒(méi)有辦法通過(guò)數(shù)組名動(dòng)態(tài)獲得數(shù)組的大小。當(dāng)你丟失a的長(zhǎng)度信息的時(shí)候,你永遠(yuǎn)不可能知道他的長(zhǎng)度。
那么 sizeof 是怎么回事呢?他不是通過(guò) a 的名字獲得 a的大小了么? —— 大錯(cuò)特錯(cuò)!
關(guān)鍵字 sizeof 產(chǎn)生的是一個(gè)編譯期常量(注1) 他的運(yùn)作方式是這樣的:
當(dāng)你寫(xiě):
sizeof a
實(shí)質(zhì)是:
sizeof ( a的類(lèi)型 )
而a的類(lèi)型是什么呢?編譯器察看 a的定義發(fā)現(xiàn), 是 int [3]
就是說(shuō),這里 sizeof a 實(shí)質(zhì)是:
sizeof ( int[3] )
完全等同于常量 12 (假定int為4字節(jié))。
考慮一個(gè)函數(shù)
void func( int a[] );
// 寫(xiě)成 int a[3] 也不會(huì)有本質(zhì)區(qū)別——也許你該試試寫(xiě)成 int (&a) [3] ?
C++規(guī)定,數(shù)組作為形參的時(shí)候,a代表數(shù)組首地址。
他的底層意義是: a 退化為了一個(gè)4字節(jié)的指針,沒(méi)有任何變量表示數(shù)組的大小會(huì)“自動(dòng)”被傳遞進(jìn)來(lái)。
我們看看這個(gè)時(shí)候 sizeof a是什么:
sizeof( 函數(shù)形參的a[] ) = sizeof( int* const ) = 4 // 當(dāng)然a[]不是合法的C++類(lèi)型
仍然不服氣?好——我們反問(wèn)一個(gè)問(wèn)題:若你是C /C++的設(shè)計(jì)者, 你怎么在兼容原有設(shè)計(jì)的基礎(chǔ)上讓void func( int a[] )同時(shí)傳遞地址和大小?
首先,a是一個(gè)變量,而且類(lèi)似數(shù)組。他必須是一個(gè)地址,否則你不知道如何索引元素。
他怎么再帶上一個(gè)變量表示他的大小呢?
擴(kuò)充 sizeof (a) 的能力?
sizeof a 必須產(chǎn)生代碼——不管是常量還是什么。 要讓他在運(yùn)行時(shí)決定 a的值, a就必須帶上他的大小信息。
1 你必須修改C標(biāo)準(zhǔn),讓C支持“兩種”數(shù)組。一種是定義處的數(shù)組,他分配大片連續(xù)內(nèi)存,和原來(lái)的C標(biāo)準(zhǔn)相同。
2 另一種是作為參數(shù)傳遞數(shù)組。 你必須傳遞地址和數(shù)組大小;這個(gè)數(shù)組實(shí)際上是一個(gè)8字節(jié)的結(jié)構(gòu){ 地址; 大小}(事實(shí)上可能更加復(fù)雜,考慮多緯數(shù)組如何實(shí)現(xiàn)? )
3 系統(tǒng)必須根據(jù)兩種不同數(shù)組分別實(shí)現(xiàn)其 []、* 、&等。 原有的數(shù)組根據(jù)其首地址偏移(這是個(gè)常量)和下標(biāo)尋址; 而參數(shù)數(shù)組則首先取“地址”內(nèi)容(這是個(gè)變量),然后根據(jù)這個(gè)地址尋址....
厄... 再考慮多維數(shù)組——聽(tīng)起來(lái)這不是一整套vector模型么?
-----------------------------------------------
注1: 對(duì)于C99支持的 flexible array ,其 sizeof 運(yùn)算是運(yùn)行時(shí)求值
posted on 2011-03-01 17:14
deercoder 閱讀(11739)
評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi):
C++