|
|||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機 | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
數(shù)組,指針問題 |
| 作者:qixiboy 欄目:單片機 |
請問下面這個函數(shù)這樣定義可以嗎? struct record{ uchar len; uchar cmd[32]; }; void now_to_last(struct record *a,struct record *b) { uchar i; uchar j; for(i=0;i<20;i++) { for(j=0;j<32;j++) { b[i].cmd[j] = a[i].cmd[j]; a[i].cmd[j] = 0; } } } |
| 2樓: | >>參與討論 |
| 作者: qixiboy 于 2006/10/29 13:03:00 發(fā)布:
有點混淆了,指針和數(shù)組可以這樣混著用嗎? |
|
| 3樓: | >>參與討論 |
| 作者: 平常人 于 2006/10/29 15:44:00 發(fā)布:
數(shù)組的名字可以當指針用! |
|
| 4樓: | >>參與討論 |
| 作者: yixiao2000 于 2006/10/30 12:30:00 發(fā)布:
可以 |
|
| 5樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/10/30 12:44:00 發(fā)布:
結(jié)構(gòu)指針訪問和結(jié)構(gòu)成員訪問是不一樣的寫法。 一個是->,一個是. void now_to_last(struct record *a,struct record *b) { uchar i; uchar j; for(i=0;i<20;i++) { for(j=0;j<32;j++) { b->cmd[j] = a->cmd[j]; a->cmd[j] = 0; } a++; b++; } } |
|
| 6樓: | >>參與討論 |
| 作者: qixiboy 于 2006/10/30 12:51:00 發(fā)布:
那這樣寫是不是就可以了呢 void now_to_last(struct record *a,struct record *b) { uchar i; uchar j; for(i=0;i<20;i++) { for(j=0;j<32;j++) { b[i]->cmd[j] = a[i]->cmd[j]; a[i]->cmd[j] = 0; } } } |
|
| 7樓: | >>參與討論 |
| 作者: mllzs 于 2006/10/30 14:21:00 發(fā)布:
這樣寫不對的! b[i]->cmd[j] = a[i]->cmd[j]; a[i]->cmd[j] = 0; 應(yīng)該為: b->cmd[j] = a->cmd[j]; a->cmd[j] = 0; |
|
| 8樓: | >>參與討論 |
| 作者: qixiboy 于 2006/10/30 17:50:00 發(fā)布:
哦 那上面平常人說“數(shù)組的名字可以當指針用!” 那反過來就不可以嗎?-----指針不能當數(shù)組的名字嗎? |
|
| 9樓: | >>參與討論 |
| 作者: IceAge 于 2006/10/30 22:29:00 發(fā)布:
指針可以當數(shù)組的名字 很多compiler可以通過 b[i].cmd[j] = a[i].cmd[j] 是可以的 與 (b+i)->cmd[j] 及 (*(b+i)).cmd[j] 等價。 不過程序應(yīng)該清晰明了,如果想使用數(shù)組,最好傳遞數(shù)組參數(shù) now_to_last(struct record a[], |
|
| 10樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/10/31 9:01:00 發(fā)布:
你的入口參數(shù)和使用方法不匹配 void now_to_last(struct record *a,struct record *b) 入口參數(shù)是結(jié)構(gòu)指針,不是結(jié)構(gòu)指針的指針,所以不不能按數(shù)組方法使用。 入口想按你的方法使用,必須 void now_to_last(struct record **a,struct record **b) 結(jié)構(gòu)指針的用法,和一般的CHAR *用法是一樣的。 |
|
| 11樓: | >>參與討論 |
| 作者: IceAge 于 2006/10/31 10:28:00 發(fā)布:
所長此言差矣 now_to_last(struct record *a,struct record *b) 沒有問題。 struct record r[20]; now_to_last(r); //可以用 a[i]. 或 (a+i)-> 結(jié)構(gòu)數(shù)組知道首地址就可以訪問,compiler 可以確定第 i 個元素首地址: ((CHAR*) a) + sizeof(struct record) * i 所長的參數(shù)類型一般是傳遞結(jié)構(gòu)指針數(shù)組,即: struct record* r[20]; now_to_last(r); void now_to_last(struct record **a,struct record **b) { r[i]->cmd[j]; // not r[i].cmd[j] } 通常用來更換結(jié)構(gòu)(即指向新結(jié)構(gòu)) |
|
| 12樓: | >>參與討論 |
| 作者: MicroMMU 于 2006/10/31 12:33:00 發(fā)布:
LZ的是正確的!我在機上驗證過了。 有點不解: 入口是指向“結(jié)構(gòu)的指針”,而在內(nèi)部引用則采用“數(shù)組方式”操作,不明白。 |
|
| 13樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/10/31 13:06:00 發(fā)布:
IceAge你說的和我說的不一樣 你只說怎么入口調(diào)用。 struct record r[20]; now_to_last(r); //可以用 a[i]. 或 (a+i)-> now_to_last內(nèi)部一定要用a->訪問,不能a[i],除非再定義結(jié)構(gòu)指針指針或顯式強行轉(zhuǎn)換。 否則,按俺第一個例子處理,采用指針++的方式。 按樓主例子,編譯器一定會有警告出現(xiàn),警告==風險。保證沒有編譯器沒有警告出現(xiàn)是程序員最基本的要求。 |
|
| 14樓: | >>參與討論 |
| 作者: MicroMMU 于 2006/10/31 13:29:00 發(fā)布:
LZ的編譯后沒警告! 不信可去試試。經(jīng)過運行得出的值確實是正確的。 后來我不用結(jié)構(gòu)指針,而用普通指針也是可以的。得出一個結(jié)論 入口為指針,在引用時可采用數(shù)組方式。 如:Function_A (UCHAR *p1,UCHAR *p2) {UCHAR A,B; A=p1[xx];//p1[xx]相當于*(p1+xx); B=p2[xx];//p1[xx]相當于*(p2+xx); } 如IceAge說。 b[i].cmd[j] = a[i].cmd[j] 是可以的 與 (b+i)->cmd[j] 及 (*(b+i)).cmd[j] 等價。 |
|
| 15樓: | >>參與討論 |
| 作者: MicroMMU 于 2006/10/31 14:00:00 發(fā)布:
實踐證明。 unsigned CHAR a[2]={1,2}; unsigned CHAR b; b=a[2]; b=*(a+2);//等同b=a[2]編譯后也是可以的。 ............................ ............................ ............................ ............................ ............................ --- --- |
|
| 16樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/10/31 15:23:00 發(fā)布:
樓上要測試的是樓主的這段: void now_to_last(struct record *a,struct record *b) { uchar i; uchar j; for(i=0;i<20;i++) { for(j=0;j<32;j++) { b[i]->cmd[j] = a[i]->cmd[j]; a[i]->cmd[j] = 0; } } } |
|
| 17樓: | >>參與討論 |
| 作者: MicroMMU 于 2006/10/31 20:30:00 發(fā)布:
我測試是下面的這段。樓上所長的肯定編譯不過 qixiboy 發(fā)表于 2006-10-29 12:45 侃單片機 ←返回版面 數(shù)組,指針問題 請問下面這個函數(shù)這樣定義可以嗎? struct record{ uchar len; uchar cmd[32]; }; void now_to_last(struct record *a,struct record *b) { uchar i; uchar j; for(i=0;i<20;i++) { for(j=0;j<32;j++) { b[i].cmd[j] = a[i].cmd[j]; a[i].cmd[j] = 0; } } } |
|
| 18樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/10/31 21:13:00 發(fā)布:
樓上的 這段代碼是極其不合格的,即使你在KEILC上沒警告,你也會在其他90%以上的編譯器上出現(xiàn)警告。根本把概念性質(zhì)的東西混淆了。所以絕對不能說這段代碼是正確的,只是碰巧結(jié)果正確。 既然是指針,就必須按指針概念處理。如果想轉(zhuǎn)換,也必須明確指出轉(zhuǎn)換。 |
|
| 19樓: | >>參與討論 |
| 作者: computer00 于 2006/10/31 22:14:00 發(fā)布:
指針跟數(shù)組名應(yīng)該是一樣的 CHAR *p; *p=2; //p[0]=2; *(p+1)=2; //p[1]=2; 在我的C語言概念里,兩者是完全等價的,倒來倒去都無所謂. p[a]等價于*(p+a),由此又有a[p],好象很多編譯器都支持,所以我懷疑編譯器就是將p[a]按照*(p+a)來處理的。 |
|
| 20樓: | >>參與討論 |
| 作者: MicroMMU 于 2006/10/31 22:32:00 發(fā)布:
不會,我在KC,與IAR C 中都試過。不會有警告。 LZ 的代碼是可以正確實現(xiàn)的。只是比較隱形難理解罷了。 你看我們定義一組數(shù)組a[10];然后再定義一入口為指針的函數(shù)void Fun(UCHAR *p) 當數(shù)組作為函數(shù)Fun的實參時,我們是不是可以這樣子寫 Fun(a); 這說明了什么呢? 說明了 單純的a這個符號代表了一個指針。對不對?當a后面加了[]符號就變成了數(shù)據(jù)了。那么們來尋找下這個a跟a[i]之間有什么關(guān)系 假設(shè)我硬是要用a 來表示a[i],只有這樣了*(a+i*j)其中j=sizeof(*a),根據(jù)*a指向類形不同j也不一樣, 上面證明了a[i] 等同*(a+i*Sizeof(*a)) 好!下面我們回到LZ的代碼 void now_to_last(struct record *a,struct record *b) { uchar i; uchar j; for(i=0;i<20;i++) { for(j=0;j<32;j++) { b[i].cmd[j] = a[i].cmd[j];---------------(1) a[i].cmd[j] = 0;_________________________(2) } } } 根據(jù)上面的證明 是不是可以將(1)中改成 *(b+i*sizeof(*b)).cmd[j] = *(a+i*sizeof(*a)).cmd[j]; (2)改成: *(a+i*sizeof(*a)).cmd[j]=0; 改后變成了: void now_to_last(struct record *a,struct record *b) { uchar i; uchar j; for(i=0;i<20;i++) { for(j=0;j<32;j++) { *(b+i * sizeof(*b)).cmd[j] = *(a+ i * sizeof(*a)).cmd[j]; *(a+i * sizeof(*a)).cmd[j]=0; } } } 是不是很清析了。函數(shù)中引用全變成了a 跟 b 了。其中sizeof(*b)因為b的類形是確定的,編譯器自動計算后代入就行了。 再將此函數(shù)逆回去就是LZ的形態(tài)了。 唉 打字也花了十幾分鐘。要頂下也。 |
|
| 21樓: | >>參與討論 |
| 作者: IceAge 于 2006/10/31 23:34:00 發(fā)布:
頂MicroMMU 數(shù)組名和指針還是有差別的,指針是變量,數(shù)組名可以不是變量, 即:指針可以當作數(shù)組名運算,而數(shù)組名不一定可以當作指針運算。 int array[20]; int* p; p = array; p++; p[0] = 1; // 可以 array++; //不可以 p[1] : 必須在運行時通過計算才能得到地址: p + 1 array[1] : 某些情況下,compiler 可以直接得到地址,因為array 可以是常數(shù),常數(shù)+1 還是常數(shù) 同意所長的這句話:既然是指針,就必須按指針概念處理。如果想轉(zhuǎn)換,也必須明確指出轉(zhuǎn)換。還是那句話:盡管沒有問題,不過程序應(yīng)該清晰明了,如果想使用數(shù)組,最好傳遞數(shù)組參數(shù),更何況對數(shù)組名和指針概念不清楚的情況下 |
|
| 22樓: | >>參與討論 |
| 作者: computer00 于 2006/10/31 23:43:00 發(fā)布:
那是指針常量和指針變量的區(qū)別了. 數(shù)組名就是指針常量,當然不能執(zhí)行自加操作了。 而普通指針,不加const修飾就是指針變量了,所以可以自加. 但是它指針的本質(zhì)是一樣的,所以用*p和p[0]是一樣的。[]實際上是變址尋址符號. |
|
| 23樓: | >>參與討論 |
| 作者: IceAge 于 2006/11/1 0:32:00 發(fā)布:
*p 和 [] 不完全一樣 int* p; int array[20]; *(p+1) 和 p[1]是一樣的, 都是在 *運行時* 變址尋址 *(p+1) 和 array[1] 不完全一樣, compiler 可以在 *編譯時* 確定array[1]的地址 |
|
| 24樓: | >>參與討論 |
| 作者: computer00 于 2006/11/1 0:41:00 發(fā)布:
我覺得還是一樣的 int array[20]; *(array+1)=100; //和 array[1]=100; 兩者一樣,編譯器照樣可以在編譯時確定地址. 所以還是指針常量和指針變量的區(qū)別,而指針用法是沒有區(qū)別的。只有常量才能在編譯時確定其值. * - 本貼最后修改時間:2006-11-1 8:33:45 修改者:computer00 |
|
| 25樓: | >>參與討論 |
| 作者: MicroMMU 于 2006/11/1 1:31:00 發(fā)布:
應(yīng)該是不一樣的。 int* p; int array[20]; *(p+1) 和 array[1] 應(yīng)該有區(qū)別。 因為 array數(shù)組在編譯時編譯器已經(jīng)分配好內(nèi)存了,所以 ARRAY數(shù)組中所有元素的地址都是固定的。 但*(p+1)不同,因為 你定義為 INT *P時它只表明了P這個變量是指向一個INT型數(shù)據(jù)的指針。至于它指向哪個數(shù)據(jù),是不確定的,比如可將外部揮發(fā)性變量賦值給它。因此在執(zhí)行*(P+1)時,編譯器將產(chǎn)生一個相加程序通過CPU運算來進行指針增長。 |
|
| 26樓: | >>參與討論 |
| 作者: PandaFeng 于 2006/11/1 2:34:00 發(fā)布:
數(shù)組在編譯時編譯器已經(jīng)分配好內(nèi)存了? 大小是定了,但地址并不一定,除非它是靜態(tài)的。 數(shù)組可以在棧中分配. |
|
| 27樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/11/1 7:19:00 發(fā)布:
討論這種寫法是沒意義的,根本就是不被允許的。 |
|
| 28樓: | >>參與討論 |
| 作者: computer00 于 2006/11/1 8:42:00 發(fā)布:
不會吧...我以前很多程序里面都是這樣寫的。 因為寫*(p+i)麻煩得很,我都是通通改成p[i],一看就明白:在p的基礎(chǔ)上偏移i個。 例如對于大端結(jié)構(gòu)的,將32bit的int型轉(zhuǎn)化為4個byte,我寫: unsigned LONG int L; unsigned CHAR B0,B1,B2,B3; B3=((unsigned CHAR *)&L)[0]; B2=((unsigned CHAR *)&L)[1]; B1=((unsigned CHAR *)&L)[2]; B0=((unsigned CHAR *)&L)[3]; 記住一條:數(shù)組名就是指針常量,即,數(shù)組名的本質(zhì)是一個指針,所以可以把它跟指針互換。 當然,定義數(shù)組和定義指針那肯定是不同的了。指針只有一個地址,而數(shù)組除了這個地址外, 還要給數(shù)組元素分配空間。但就數(shù)組名和指針常量的用法上來說,應(yīng)該是沒有區(qū)別的。 |
|
| 29樓: | >>參與討論 |
| 作者: fsaok 于 2006/11/1 8:54:00 發(fā)布:
未免顯然太迂腐了 在 C 語言中,數(shù)組和指針本來就是一回事。 對于 void now_to_last(struct record *a,struct record *b)函數(shù)來說,就是要傳遞數(shù)組的地址去處理, 而在調(diào)用now_to_last() 的程序,對會有 b[i].cmd[j]的處理, 因此,b[i].cmd[j] = a[i].cmd[j]; 比 b[i]->cmd[j] = a[i]->cmd[j];的寫法來得清晰, 編譯的結(jié)果是一樣的,為什么不采取b[i].cmd[j] = a[i].cmd[j]; 的寫法呢 |
|
| 30樓: | >>參與討論 |
| 作者: eleven11 于 2006/11/1 9:02:00 發(fā)布:
看看computer00 水平就是不一樣 |
|
| 31樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/11/1 9:02:00 發(fā)布:
一定是->操作,否則概念不清。出錯的時候都不知道怎么錯的 |
|
| 32樓: | >>參與討論 |
| 作者: 農(nóng)民講習所 于 2006/11/1 9:06:00 發(fā)布:
很多人都混淆指針和數(shù)組概念 兩者有聯(lián)系,又有根本性的區(qū)別。 一般來說,兩者的聯(lián)系主要存在于指針初始化的時候。把指針(特別是結(jié)構(gòu)指針)當數(shù)組用,根本是概念的混淆。 |
|
| 33樓: | >>參與討論 |
| 作者: computer00 于 2006/11/1 9:25:00 發(fā)布:
關(guān)于->和.,前者用在指針,后者用在結(jié)構(gòu)體本身 例如 typedef struct OSMsg { volatile uint32 MsgType; }OSMsg; OSMsg *p; OSMsg Msg; p=&Msg; //將p指向Msg p->MsgType=1; // 跟(&Msg)->MsgType=1; 以及 Msg.MsgType=1; 以及 (*p).MsgType=1; 等價 //也可以改寫成p[0].MsgType=1; 如果我們再弄一個數(shù)組,即 OSMsg *p; OSMsg Msg[2]; p=Msg; //跟p=&(Msg[0]); 等價 p->MsgType=1; //也可以寫成Msg->MsgType=1; 或者繞個彎子 (&(Msg[0]))->MsgType=1; //還可以寫成(*p).MsgType=1; 和 p[0].MsgType=1; //還可以寫成(*Msg).MsgType=1; 和 Msg[0].MsgType=1; //(以上都是在p=Msg時才成立,我們現(xiàn)在只討論用法) 用->時是指針,用.時是本身。 像后面這個例子,p和Msg(數(shù)組名)都是指針,所以用->訪問其成員。 而*p,*Msg,p[0],Msg[0],都變成結(jié)構(gòu)體本身了,所以用.訪問其成員。 由此可以得出對于結(jié)構(gòu)體指針p,下列三者等價: p-> 跟 (*p). 跟 (p[0]). 對于第三種寫法,單個結(jié)構(gòu)體時不太好理解,如果p是一個指向結(jié)構(gòu)體數(shù)組的 指針的話,就容易理解了。 * - 本貼最后修改時間:2006-11-1 9:40:24 修改者:computer00 |
|
| 34樓: | >>參與討論 |
| 作者: MicroMMU 于 2006/11/1 9:48:00 發(fā)布:
00 你的程序移殖性不好。 對于KC是正確的。 B3=((unsigned CHAR *)&L)[0]; B2=((unsigned CHAR *)&L)[1]; B1=((unsigned CHAR *)&L)[2]; B0=((unsigned CHAR *)&L)[3]; 但對于其它編譯器就要反過來。 B3=((unsigned CHAR *)&L)[3]; B2=((unsigned CHAR *)&L)[2]; B1=((unsigned CHAR *)&L)[1]; B0=((unsigned CHAR *)&L)[0]; 我以前喜歡用這種,但后來發(fā)覺移到別的上面就有問題了。 |
|
| 35樓: | >>參與討論 |
| 作者: IceAge 于 2006/11/1 10:03:00 發(fā)布:
computer00, 你的例子沒有錯 不過我們討論的是指與數(shù)組名的不同,而不是相同之處。 指針是一種數(shù)據(jù)類型,與其它的數(shù)據(jù)類型不同的是指針是一種“用來存放地址值的”變量 MSDN: A "pointer declaration" names a pointer variable and specifies the type of the object to which the variable points. A variable declared as a pointer holds a MEMORY address. 最大的區(qū)別: 指針是個變量,即占用內(nèi)存。數(shù)組名(指的是非指針變量的數(shù)組名)可以是常數(shù),不一定要占用內(nèi)存。不過數(shù)組名賦值于指針,就沒有區(qū)別了 c/c++數(shù)組名與指針區(qū)別深入探索 |
|
| 36樓: | >>參與討論 |
| 作者: computer00 于 2006/11/1 10:04:00 發(fā)布:
MicroMMU,的確如此 所以我在前面指定它在大端模式下。 用移位操作的話可移植性就好了。 B0=(L>>24)&0xFF; B1=(L>>16)&0xFF; B2=(L>>8)&0xFF; B3=(L)&0xFF; 并且一些編譯器會對它優(yōu)化,生成跟 B3=((unsigned CHAR *)&L)[0]; B2=((unsigned CHAR *)&L)[1]; B1=((unsigned CHAR *)&L)[2]; B0=((unsigned CHAR *)&L)[3]; 一樣的直接對內(nèi)存操作的指令。是否所有編譯器都能如此優(yōu)化,偶就不清楚了。 當然,你也可以用個宏來進行選擇,不過也甚是麻煩。 #ifdef BigEnd B3=((unsigned CHAR *)&L)[0]; B2=((unsigned CHAR *)&L)[1]; B1=((unsigned CHAR *)&L)[2]; B0=((unsigned CHAR *)&L)[3]; #else #ifdef LittleEnd B3=((unsigned CHAR *)&L)[3]; B2=((unsigned CHAR *)&L)[2]; B1=((unsigned CHAR *)&L)[1]; B0=((unsigned CHAR *)&L)[0]; #else error #endif #endif |
|
| 37樓: | >>參與討論 |
| 作者: computer00 于 2006/11/1 10:21:00 發(fā)布:
指針有指針常量和指針變量之分 int * const p = 100; int x[1]; *p=2; p[0]=2; *x=3; x[0]=3; 都可以。 事實上數(shù)組名就是一個指針常量,它作為常數(shù)是理所當然的。 由于這個區(qū)別,編譯器可能對他們的處理上會不一樣。例如對于用數(shù)組名訪問的,可能會生成直接尋址指令, 而用指針訪問的,則可能會生成寄存器變址尋址指令。當然這個不是絕對的。 我一直把數(shù)組名歸類到指針里面的,它是一種指針常量。 |
|
| 38樓: | >>參與討論 |
| 作者: fsaok 于 2006/11/1 10:31:00 發(fā)布:
似乎明白 我一向都是像圈圈那樣寫程序調(diào)用的。 不過,我可能是錯的。 對于樓主的函數(shù)參數(shù)部分,按某些人的說話,可能應(yīng)該寫成這樣 void now_to_last(struct record a[], struct record b[]); ----------------------------- 想起另一個函數(shù), CHAR *strcpy (CHAR *dest, /* destination string */ CHAR *src); /* source string */ 剛好,我有兩個數(shù)組,有這么一個程序, void tst_strcpy (void) { CHAR buf [21]; CHAR s [] = "TEST String"; strcpy (buf, s); } 這s[] buf[]都是數(shù)組, 似乎我要重寫一個strcpy()函數(shù)了,否則,不規(guī)范呀 |
|
| 39樓: | >>參與討論 |
| 作者: MicroMMU 于 2006/11/1 10:47:00 發(fā)布:
如果 改成void now_to_last(struct record a[], struct record b[])應(yīng)該是一樣的。 用數(shù)組作函數(shù)的形參。在實際傳遞過程是以指針形式傳遞。 * - 本貼最后修改時間:2006-11-1 12:47:35 修改者:MicroMMU |
|
| 40樓: | >>參與討論 |
| 作者: computer00 于 2006/11/1 11:13:00 發(fā)布:
不見得 我將string.h里面的聲明 extern CHAR *strcpy (CHAR *s1, CHAR *s2); 改成 extern CHAR *strcpy (CHAR s1[], CHAR s2[]); 編譯通過,并且運行結(jié)果也一樣,編譯的代碼也完全一樣。 我自己寫一個函數(shù)測試也一樣, void TEST(unsigned CHAR *p) 跟 void TEST(unsigned CHAR p[]) 完全一樣。它根本就是把p[]當作了*p。 我函數(shù)定義時用void TEST(unsigned CHAR *p), 而函數(shù)聲明我則用void TEST(unsigned CHAR p[]), 編譯結(jié)果也完全一樣。兩個怎么調(diào)都沒關(guān)系。 這是在keil UV2下的測試結(jié)果。 * - 本貼最后修改時間:2006-11-1 11:14:54 修改者:computer00 |
|
| 41樓: | >>參與討論 |
| 作者: computer00 于 2006/11/1 11:22:00 發(fā)布:
似乎它根本不理數(shù)組大小…… void TEST(unsigned CHAR data p[65535]) { *p=20; } 51只有128字節(jié),可偶給它一個65535這么大的數(shù)組,它照接收不誤,可見在keil里并未對這樣的數(shù)組分配空間,而是當作指針處理了。 |
|
| 42樓: | >>參與討論 |
| 作者: fsaok 于 2006/11/1 11:41:00 發(fā)布:
幾點問題 經(jīng)查閱資料,得出幾個結(jié)論 (1)數(shù)組名的內(nèi)涵在于其指代實體是一種數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)就是數(shù)組; (2)數(shù)組名的外延在于其可以轉(zhuǎn)換為指向其指代實體的指針,而且是一個指針常量; (3)指向數(shù)組的指針則是另外一種變量類型,僅僅意味著數(shù)組的存放地址! (4)數(shù)組名作為函數(shù)形參時,在函數(shù)體內(nèi),其失去了本身的內(nèi)涵,僅僅只是一個指針,所以 CHAR *strcpy (CHAR *s1, CHAR *s2); 和 CHAR *strcpy (CHAR s1[], CHAR s2[]); 的表達式,其實就是一回事。 有趣的是 sizeof(s) 這種表達式, 比如 對于數(shù)組 CHAR s[10] 來說, sizeof(s) 是 10 在 void tst(CHAR s[]) 函數(shù)中, sizeof(s)的肯定不會是10 而是指針的長度, 如果s[]是另一個文件里定義的話,通過 extern CHAR s[];定義的話 sizeof(s)的結(jié)果卻是 0 |
|
| 43樓: | >>參與討論 |
| 作者: 赤鑄 于 2006/11/1 15:04:00 發(fā)布:
居然爭論起這個了 C 語言里數(shù)組和指針的規(guī)定的確有些混亂 簡單說,數(shù)組非常特殊,因為數(shù)組作為整體實際上 不可操控(access)! 對于別的類型 T,你可以 T a, b; a = b; 但對于數(shù)組,你不能 typedef int T[3]; T a, b; a = b; 你所能操控的,只有兩樣: 1. 數(shù)組入口地址,通過數(shù)組名 2. 數(shù)組元素,通過數(shù)組入口地址和[] 既然不能整體賦值,數(shù)組實際上根本不能用作函數(shù)形參! 函數(shù)函數(shù)形參里那種 a[] 的寫法只能視為指針類型的另一種“書寫形式”,而不應(yīng)視為數(shù)組! * - 本貼最后修改時間:2006-11-1 15:07:13 修改者:赤鑄 |
|
| 44樓: | >>參與討論 |
| 作者: qixiboy 于 2006/11/1 16:55:00 發(fā)布:
非常感謝大家的討論。 總結(jié)了一下大家說的,這種寫法是可以的,但是并不提倡是吧! |
|
| 45樓: | >>參與討論 |
| 作者: yanfengzhu 于 2006/11/1 20:23:00 發(fā)布:
數(shù)組名跟指針還是有區(qū)別的。 至少你在一個文件中這樣定義了一個數(shù)組, CHAR a[10]; 你絕對不可以在另一個文件里這樣聲明。 extern CHAR *a; 訪問指針所指的變量是兩次尋址,而訪問數(shù)組成員是一次尋址的。 指針可以做左值,函數(shù)名卻不可以。 但是,摟主的寫法是完全正確的,如果有哪個編譯器產(chǎn)生error or warning. 我覺得9.9成可以把它拉進回收站。 我想樓主你是不會把它改成這樣吧 void now_to_last(struct record a[],struct record b[]); 這會顯得你n不專業(yè),翻遍所有c編譯器的庫函數(shù)頭文件,我想你也找不出這種寫法的。 c語言的參數(shù)傳遞就只有值傳遞和指針傳遞。其實就只有值傳遞,我覺得指針傳遞可認為是指針的值的傳遞。而值傳遞是通過copy值來實現(xiàn)的。也就是說要求函數(shù)參數(shù)是一個左值。而函數(shù)名可不是左值,因此在函數(shù)參數(shù)中數(shù)組的寫法是沒有意義的,它的實現(xiàn)都是指針。 * - 本貼最后修改時間:2006-11-1 22:17:48 修改者:yanfengzhu |
|
| 46樓: | >>參與討論 |
| 作者: IceAge 于 2006/11/1 21:41:00 發(fā)布:
大家說的都有一定的道理 To computer00: int * const p = (int*) 100; 你可能是誤解了 int* const, int* const也是變量,要占用空間, 只不過是 compiler 加以語法限制而以,你總是可以繞過compiler 改變 p, 如: int** a = (int*) & p; *a = (int*) 0x1000; 而全局/靜態(tài)數(shù)組名可以是 *常數(shù)*,不是變量,不占用空間,compiler 在編譯是可能會直接把常數(shù)地址嵌入在代碼里。 To yanfengzhu: void now_to_last(struct record a[],struct record b[]); 是沒有問題的,這里的 a, b 是指針變量,可以被賦值為數(shù)組名常數(shù),或是其他指針的值。 |
|
| 47樓: | >>參與討論 |
| 作者: computer00 于 2006/11/1 22:05:00 發(fā)布:
不見得。有些編譯器會將const處理到代碼段去。 加了const就是常量了,不再是變量。 同樣,yanfengzhu所說的,不能做左值,那是因為它是常量。任何一個常量都不可以做左值,而并非數(shù)組名的專利。 |
|
| 48樓: | >>參與討論 |
| 作者: yanfengzhu 于 2006/11/1 22:39:00 發(fā)布:
呵呵。 to IceAge: 我并不是說這樣不行,只是說這不符合大部分c程序員的習慣,這樣寫出來也顯得自己很不專業(yè)。 to computer00: 加了const并不一定就是常量,還可以通過指針來改變它的值的,只能說它是不易變的,而且正常來說是不會編譯到代碼段去的,一般是編譯到已初始化變量段里面。 |
|
| 49樓: | >>參與討論 |
| 作者: sanwa_chen 于 2006/11/2 11:45:00 發(fā)布:
指針總是有爭論 "一定是->操作,否則概念不清。出錯的時候都不知道怎么錯的" 我贊成! 用2個編譯沒有出錯不是說沒有問題,你多換幾個試試看吧 可以放到PIC的C18下,PCC-C什么的看看 可能不規(guī)范(或不正確)的寫法,編譯后運行結(jié)果對了,但是問題仍然被忽略了. |
|
| 50樓: | >>參與討論 |
| 作者: mohanwei 于 2006/11/2 12:23:00 發(fā)布:
指針可以重新賦值,數(shù)組名卻不可以(數(shù)組名是常量) 這是它們之間最大的區(qū)別點。 |
|
| 51樓: | >>參與討論 |
| 作者: qixiboy 于 2006/11/2 12:32:00 發(fā)布:
還真叫yanfengzhu說對了 昨天看了大家的討論,為了看的明白和規(guī)范,我還真把程序?qū)懗桑?br>void now_to_last(struct record a[],struct record b[]); 呵呵,我本來就是很不專業(yè),向大家好好學習!。。! |
|
| 52樓: | >>參與討論 |
| 作者: fsaok 于 2006/11/2 16:46:00 發(fā)布:
其實 其實, void now_to_last(struct record a[],struct record b[]); 和 void now_to_last(struct record * a, struct record * b); 真的不是完全一樣,因為 struct record *a 是個指針,而 struct record a[]中的a 就變成了常量指針, 對于 struct record * a 來說,在函數(shù)中,肯定可以進行 a++ 之類的操作, 這也許就是所謂錯也不知道錯在什么地方的問題 |
|
| 53樓: | >>參與討論 |
| 作者: yanfengzhu 于 2006/11/2 19:57:00 發(fā)布:
樓上你就不要誤道樓主了。 對于函數(shù)的形參: int a[] 和 int *a 是完全等價的。 要注意這里說的是函數(shù)的形參哦!這句話出自《C語言參考手冊》。(據(jù)說c語言標準的定制都還要參考此書) 至于為什么等價,我在上面已經(jīng)說了。 而為什么不用這種寫法 void now_to_last(struct record a[],struct record b[]); 是因為這初看給人一種把一整個數(shù)組傳入的感覺,因此在標準的庫函數(shù)頭文件里,是見不到這樣寫的,幾乎都是已指針的形式來寫。 |
|
| 54樓: | >>參與討論 |
| 作者: IceAge 于 2006/11/2 21:08:00 發(fā)布:
呵呵, 還在討論 看來大家對于指針,數(shù)組名應(yīng)該沒有什么異議了 關(guān)于 void now_to_last(struct record a[],struct record b[]); void now_to_last(struct record * a, struct record * b); 沒有什么本質(zhì)的區(qū)別,唯一的區(qū)別在于語法!斑@樣寫出來也顯得自己很不專業(yè)“ 實在不敢茍同,個人認為,程序應(yīng)應(yīng)該清晰明了,不應(yīng)該是 “顯得專業(yè)“。a[] 明確的告訴你 a 是數(shù)組(當然也是指針),請在程序里當做數(shù)組使用。另外,標準的庫函數(shù)頭文件因為歷史原因很晦澀,經(jīng)常被人詬病,最好不要以其作為楷模。 |
|
| 55樓: | >>參與討論 |
| 作者: IceAge 于 2006/11/2 22:00:00 發(fā)布:
補充: void now_to_last(struct record a[],struct record b[]); 其實也不是很好. 數(shù)組有邊界: void now_to_last(struct record a[], struct record b[],int size); |
|
| 56樓: | >>參與討論 |
| 作者: computer00 于 2006/11/2 23:38:00 發(fā)布:
暈了....何必硬要將數(shù)組名獨立出來?它根本就是一個指針. C語言又不做下標越界檢測,是數(shù)組名還是指針有啥區(qū)別?數(shù)組名就是指針常量. 按照這個用,不會出錯的.一看到數(shù)組名,就要條件反射,它是一個指針. |
|
| 57樓: | >>參與討論 |
| 作者: yanfengzhu 于 2006/11/3 21:22:00 發(fā)布:
如果sizeof(str) == sizeof(pstr); CHAR str[] = "0123456789"; CHAR * const pstr = "0123456789"; 如果sizeof(str) == sizeof(pstr); 我就覺得一樣了。 |
|
| 58樓: | >>參與討論 |
| 作者: fsaok 于 2006/11/4 7:26:00 發(fā)布:
大實話 數(shù)組名就是指針常量. 按照這個用,不會出錯的.一看到數(shù)組名,就要條件反射,它是一個指針 其他所謂規(guī)范,都是個人的喜好 |
|
| 59樓: | >>參與討論 |
| 作者: 030421411 于 2006/11/4 8:42:00 發(fā)布:
嘿嘿黑 可以 只要不出錯就行 |
|
| 60樓: | >>參與討論 |
| 作者: 赤鑄 于 2006/11/7 0:06:00 發(fā)布:
標準 C/C++ 其實沒有非字面“常量”,即符號常量 簡單說,1,2,3,"a","b"都屬于字面常量,數(shù)組名也屬于“字面常量”,用標識符表示的就叫符號常量(宏定義不算) 其它高級語言中有符號常量,例如Pascal中可定義 const pi = 3.14; 但 C 里面 const pi = 3.14; 純屬 const int pi = 3.14; 的縮寫,即 pi 為“被初始化為 3.14 的、加 const 修飾符的 int 型變量” 至于 computer00 說的編譯到代碼段,屬于代碼優(yōu)化范疇,而不是語言自身定義。即使優(yōu)化了,編譯器也只是將用到 pi 的值(僅僅是值)的地方直接替換成 3.14,那個名叫 pi 的變量依然存在,你依然可以 int * pPi = (int *) π *pPi = 2.71828; 此后 pi 變量的值便變成了 2.71828。 這時就發(fā)生了混亂。調(diào)試程序的時候,你可能會發(fā)現(xiàn):pi 變量已經(jīng)是 2.71828,但用到 pi 的地方分明仍然用的是 3.14(只要優(yōu)化等級足夠高) |
|
| 61樓: | >>參與討論 |
| 作者: computer00 于 2006/11/7 0:35:00 發(fā)布:
恩,是有這個區(qū)別. |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |