main()
{
inta[5]={1,2,3,4,5};
int*ptr=(int*)(&a+1);
printf("
%d,%d",*(a+1),*(ptr-1));
}
輸出結(jié)果是多少?
請(qǐng)解釋一下原因...
網(wǎng)友評(píng)論:char*a;和chara[];的區(qū)別。
網(wǎng)友評(píng)論:這個(gè)問題也沒有必要討論下去了
PS:怎么加簽名?
網(wǎng)友評(píng)論:只有一種規(guī)則!它實(shí)際上是以一種相當(dāng)優(yōu)雅的方式把我們這些完全不同的概念聯(lián)系在一起。
《C與指針》P141:
首先讓我們學(xué)習(xí)一個(gè)概念,它被許多人認(rèn)為是C語言設(shè)計(jì)的一個(gè)缺陷。但是,這個(gè)概念實(shí)際上是以一種相當(dāng)優(yōu)雅的方式把一些完全不同的概念聯(lián)系在一起的。
考慮下面的聲明:
inta[5];
a[1]的類型是整型,那a的類型又是什么?它所表示的又是什么?一個(gè)合乎邏輯的答案是它表示整個(gè)數(shù)組,但事實(shí)并非如此。
在C中,在幾乎所有使用數(shù)組名的表達(dá)式中,數(shù)組名的值是一個(gè)指針常量,也就是數(shù)組第一個(gè)元素的地址。它的類型取決于數(shù)組元素的類型:如果它們是int類型,那么數(shù)組名就是“指向int的常量指針”;如果它們是其它類型,那么數(shù)組名的類型就是“指向‘其他類型’的常量指針”。
數(shù)組具有一些和指針完全不同的特征。例如,數(shù)組具有確定數(shù)量的元素,而指針只是一個(gè)標(biāo)量值。編譯器用數(shù)組名來記住這些屬性。只有數(shù)組名在表達(dá)式中使用時(shí)編譯器才會(huì)為它產(chǎn)生一個(gè)指針常量。
注意這個(gè)值是指針常量,而不是指針變量,你不能修改常量的值。你只要稍微回顧一下,就會(huì)認(rèn)為這個(gè)限制是合理的:指針常量所指向的是
內(nèi)存中數(shù)組的起始位置。如果修改這個(gè)指針常量,唯一可行的操作就是把整個(gè)數(shù)組移動(dòng)到內(nèi)存的其他位置。但是,程序完成鏈接之后,內(nèi)存中數(shù)組的位置是固定的。所以當(dāng)程序運(yùn)行時(shí),再想移動(dòng)數(shù)組就為時(shí)已晚了。因此,數(shù)組名的值是一個(gè)指針常量。
只有在兩種場(chǎng)合下,數(shù)組名并不用指針常量來表示:
1、當(dāng)數(shù)組名作為sizeof操作符的操作數(shù)時(shí):sizeof返回整個(gè)數(shù)組的長(zhǎng)度,而不是指向數(shù)組的指針的長(zhǎng)度。
2、當(dāng)數(shù)組名作為單目操作符的操作數(shù)時(shí):取一個(gè)數(shù)組名的地址所產(chǎn)生的是一個(gè)指向該數(shù)組的指針,而不是一個(gè)指向某個(gè)指針常量值的指針。
個(gè)人看法:既然說了“在C中......”那么現(xiàn)今所有的C都符合這個(gè)“相當(dāng)優(yōu)雅的”規(guī)則。如果是“有的C編譯器這樣,另一些編譯器那樣,......”那么這本世界流行的《C與指針》還不如我們這場(chǎng)討論有價(jià)值?
網(wǎng)友評(píng)論:俺喜歡C++和delphi,討厭C,所以干什么都先想到"數(shù)組"或結(jié)構(gòu)(類)~~~
例如俺這幾天發(fā)了一帖水文:DSP281X變量地址數(shù)組定位方法
細(xì)心的人會(huì)看出來:
優(yōu)秀的編譯器對(duì)指針/數(shù)組/結(jié)構(gòu)成員變量/結(jié)構(gòu)指針的成員變量
等訪問最終的優(yōu)化代碼幾乎是相同的.
00說的:在keil51上a==&a
俺認(rèn)為可能純屬巧合~~~
如果:
xdataunsignedi;
若此時(shí)i==&i俺真的再不玩51了~~~
網(wǎng)友評(píng)論:51C編譯器在處理一個(gè)數(shù)組名/函數(shù)名時(shí),首先從符號(hào)表中查詢有沒有這個(gè)名字:
1、如果有,那么它肯定也相應(yīng)有固定的地址。這時(shí)將被編譯為立即尋址或者直接尋址方式訪問。如果用指針間接方式訪問,那純粹是“知易行難”。
2、如果符號(hào)表中沒有這個(gè)名字(動(dòng)態(tài)建立?)將采用指針間接尋址方式——指針用于訪問無名地址。而數(shù)組和函數(shù)都是有名字的。
3、再舉個(gè)例子:
intf(int);
int(*pf)(int)=f;//本應(yīng)寫為...=&f;這就像pf=&f;/pf=f;兩者對(duì)編譯器來說完全一樣,“&”操作符只是顯式地說明了編譯器將隱式執(zhí)行的任務(wù)。下面的3種函數(shù)調(diào)用方式,結(jié)果一樣效率大不同。
f(55);//立即尋址
(*pf)(55);//間接尋址
pf(55);//間接尋址
后兩個(gè)式子編譯代碼完全一樣。比第一個(gè)長(zhǎng)N倍。
網(wǎng)友評(píng)論:正如wxj1952所述,在編譯器優(yōu)化時(shí),C默認(rèn)了很多強(qiáng)制轉(zhuǎn)換,很多在C++上是不允許的,因?yàn)檫@樣很不安全,應(yīng)該顯式的轉(zhuǎn)換.
拿數(shù)組來說,第1個(gè)數(shù)值的位置就是數(shù)組的物理位置即存儲(chǔ)地址.結(jié)構(gòu)也類同.
所以,A,&A,&A[0]都表示數(shù)組的首地址.
例如:
&A[0]&A[1]&A[2]
A數(shù)組地址0x1000,0x1002,0x1004
A[0]A[2]A[2]
A數(shù)組數(shù)值0x00,0x01,0x02
而對(duì)于一般變量來說
&a
a變量的地址0x2000
a
a變量的數(shù)值0x00
用c語言來表述:
unsignedintA[3]at0x1000={0,1,2};
unsignedintaat0x2000=0;
若:
unsignedint*p;
p=A;
p=&A[0];
p=A[0];肯定錯(cuò)因?yàn)樽笾凳侵羔樧兞縫,應(yīng)該是指針即地址
而右值是數(shù)組第1個(gè)單元A[0]的數(shù)值而非地址本身!
但是我的A[0]內(nèi)就是我需要的地址呢???當(dāng)然是要做強(qiáng)制轉(zhuǎn)換了
即:
p=(unsignedint*)A[0];
但是一般變量很容易誤導(dǎo).
p=&a;//正確
p=a;//我暈!!!a的地址&a是0x2000,而0x2000的內(nèi)容a是0.
以下都能通過嗎???
p=(unsignedint*)0x2000;//知道a的地址
if(p==&a)
{
puts("這個(gè)俺明白");
}
if(p==a)
{
puts("這個(gè)是做夢(mèng)吧,除非編譯器認(rèn)為左值是指針右值肯定為指針即a的地址");
}
else
{
puts("俺堅(jiān)持p!=a的說明");
}
故菜農(nóng)認(rèn)為:
即使編譯器認(rèn)為左值是指針,右值肯定為指針即地址.
那么也應(yīng)該養(yǎng)成區(qū)分a和&a的好習(xí)慣~~~
否則程序移植到C++上就要漫天找錯(cuò)了~~~
網(wǎng)友評(píng)論:高級(jí)語言中定義的各種類型,在底層實(shí)現(xiàn)上都會(huì)失去其意義,所以底層代碼處理數(shù)組,結(jié)構(gòu)抑或是指針的方式是一樣的
另外,C++和Delphi?應(yīng)該是C++和ObjectPascal吧。
偶稀飯Pascal的原因也包含hotpower所說的2點(diǎn),1是可以不使用指針,減少出錯(cuò)的機(jī)會(huì);2是強(qiáng)類型匹配。不過Delphi太貴,偶用Lazarus或者TurboDelphi
偶看的書少,我對(duì)C的理解只是簡(jiǎn)單的按照規(guī)范文檔的說明。
我寫的代碼也從來沒有由于我理解不對(duì)而出問題,至于別人怎么理解就和我沒有關(guān)系了,不過我是建議不要使用默認(rèn)的類型轉(zhuǎn)換
網(wǎng)友評(píng)論:圈圈說的a是指樓主inta[5]={1,2,3,4,5};中的數(shù)組名,
而hot好像理解為了一般標(biāo)量xdataunsignedinta;
2個(gè)人說的兩回事。
數(shù)組名/函數(shù)名不是標(biāo)量,編譯器將以一種優(yōu)雅的方式特殊對(duì)待處理。
例如:
int*ptr=&a;或者int*ptr=a;都是一樣的。ptr都等于0x22(假定data地址。)
printf("
%#x,%#x",a,ptr);結(jié)果:0x22,0x22。
ptr=a;左值ptr是地址,右值a是常量指針a的值(0x22)。概念上沒問題。
網(wǎng)友評(píng)論:所以討論一個(gè)沒人用的寫法沒意義啊
映像中途只有看到過一次&a的用法
#definesizeof(a)((char*)(&(a)+1)-(char*)&(a))
順便提一下32樓的宏:
#defineFLASH(x)(*((volatileunsignedchar*)0x8000+x))
最好寫成
#defineFLASH(x)(*((volatileunsignedchar*)0x8000+(x)))
網(wǎng)友評(píng)論:非常完美~~~
希望Delphi迷喜歡~~~
相關(guān)鏈接:http://blog.ednchina.com/hotpower/11729/message.aspx
網(wǎng)友評(píng)論:哈哈~~~
當(dāng)x為復(fù)雜的表達(dá)式時(shí):
#defineFLASH(x)(*((volatileunsignedchar*)0x8000+x))
中x的有部分可能與0x8000先"亂搞"~~~~
#defineFLASH(x)(*((volatileunsignedchar*)0x8000+(x)))
俺以前就有過"慘痛"的教訓(xùn)~~~
開始:
#defineLedChar0LedSegA+LedSegB+LedSegC+LedSegD+LedSegE+LedSegF
//...................................
實(shí)戰(zhàn)出錯(cuò)找了一天才想到了是宏bug~~~
以后俺都是:
#defineLedChar0(LedSegA+LedSegB+LedSegC+LedSegD+LedSegE+LedSegF)
#defineLedChar1(LedSegB+LedSegC)
#defineLedChar2(LedSegA+LedSegB+LedSegD+LedSegE+LedSegG)
#defineLedChar3(LedSegA+LedSegB+LedSegC+LedSegD+LedSegG)
#defineLedChar4(LedSegB+LedSegC+LedSegF+LedSegG)
#defineLedChar5(LedSegA+LedSegC+LedSegD+LedSegF+LedSegG)
#defineLedChar6(LedSegA+LedSegC+LedSegD+LedSegE+LedSegF+LedSegG)
#defineLedChar7(LedSegA+LedSegB+LedSegC)
#defineLedChar8(LedSegA+LedSegB+LedSegC+LedSegD+LedSegE+LedSegF+LedSegG)
#defineLedChar9(LedSegA+LedSegB+LedSegC+LedSegD+LedSegF+LedSegG)
#defineLedCharA(LedSegA+LedSegB+LedSegC+LedSegE+LedSegF+LedSegG)
#defineLedCharB(LedSegC+LedSegD+LedSegE+LedSegF+LedSegG)
#defineLedCharC(LedSegA+LedSegD+LedSegE+LedSegF)
#defineLedCharD(LedSegB+LedSegC+LedSegD+LedSegE+LedSegG)
#defineLedCharE(LedSegA+LedSegD+LedSegE+LedSegF+LedSegG)
#defineLedCharF(LedSegA+LedSegE+LedSegF+LedSegG)
相關(guān)鏈接:/club/bbs/ShowAnnounce.asp?id=2928997
網(wǎng)友評(píng)論:39樓給出的宏定義:
映像中途只有看到過一次&a的用法
#definesizeof(a)((char*)(&(a)+1)-(char*)&(a))
雖然俺不知是干什么的,但卻聯(lián)想到:
&a+1==a+1嗎???
網(wǎng)友評(píng)論:根本來說,由于C的歷史所致,對(duì)C中數(shù)組名的“定義”是存在二義性的。好在存在一個(gè)自然的解決途徑,就是“域外定義”。
正如我前面所述,對(duì)于一個(gè)指針而言談?wù)撈涑叽绱笮∈菦]有意義的,因此作為sizeof的定義拓廣,令sizeof(cA)為cA數(shù)組的整體尺寸不會(huì)存在什么矛盾。另外由于cA是一個(gè)常量指針,取其地址也是沒有意義的,同樣作為定義拓廣將&cA理解成一個(gè)指向數(shù)組整體的指針也未成不可。
一般情況下,二義性沒啥不好,只要不出現(xiàn)歧義就行。在標(biāo)準(zhǔn)C++中,由于多重繼承(VC未采用)就導(dǎo)致了二義性的出現(xiàn)。因?yàn)闆]法采取“域外定義”,為了避免歧義的出現(xiàn),就加入了一系列的額外規(guī)定(如虛類等)。
但從另外的角度來看,作為一個(gè)好的習(xí)慣,盡量別去碰那些費(fèi)腦漿的二義性。于人于己都沒啥好處。
網(wǎng)友評(píng)論:LZ的題是C程序,在所有最新C編譯器下均編譯通過。37樓用C++編譯器編譯通不過,于是,以此為論據(jù),用C編譯器的人,都是概念不清。
這討論的是C數(shù)組與指針的概念,拿C++來做論據(jù),以證明自己是對(duì)的,不太好吧。
“取一個(gè)數(shù)組名的地址所產(chǎn)生的是一個(gè)指向該數(shù)組的指針,而不是一個(gè)指向某個(gè)指針常量值的指針。”
Kenneth的這本經(jīng)典著作是不是寫錯(cuò)了?抑或C語言創(chuàng)造者比我們遜多了?
網(wǎng)友評(píng)論:GCCOK了吧?
編譯器:AVR-GCC4.3
inta[3]={1,2,3};
int*p=&a+1;//warning:initializationfromincompatiblepointertype
inttmp=*p;//warning:arraysubscriptisabovearraybounds
指針類型不兼容為什么只是一個(gè)警告?GCC為什么不把類型不兼容的詳細(xì)類型列出?
編譯器的差別而已,GCC會(huì)自動(dòng)轉(zhuǎn)換類型,并發(fā)出一個(gè)警告,而操作上都是一樣的
第二個(gè)警告是不是有些驚悚?
其實(shí)是因?yàn)閮?yōu)化登記,使用-O0就沒有第二個(gè)警告,這里也可以看出GCC的優(yōu)化方式(猜想):簡(jiǎn)化為inttmp=*(int*)(&a+1);
“取一個(gè)數(shù)組名的地址所產(chǎn)生的是一個(gè)指向該數(shù)組的指針,而不是一個(gè)指向某個(gè)指針常量值的指針。”是你說的那本書里的?
網(wǎng)友評(píng)論:#defineFLASH((volatileunsignedchar*)0x8000)
/*----------------------------------------------------------
另類的"數(shù)組"訪問,外擴(kuò)的SST39VF800A從0x8000開始
voidFlashObj::ChipErase(void)
{
FLASH[0x5555]=0xaa;
FLASH[0x2AAA]=0x55;
FLASH[0x5555]=0x80;
FLASH[0x5555]=0xaa;
FLASH[0x2AAA]=0x55;
FLASH[0x5555]=0x10;
Wait(0x5555);
}
voidFlashObj::Wait(unsignedintaddress)
{
unsignedinttemp,val;
do{
val=FLASH[address];
__nop();
temp=FLASH[address];
__nop();
}
while(((val^temp)&(1<<BIT6))!=0);
}
----------------------------------------------------------*/
思考一下,在此狀況下是否還存在sizeof(FLASH)和&FLASH。
網(wǎng)友評(píng)論:Constraints
1Oneoftheexpressionsshallhavetype‘‘pointertoobjecttype’’,theotherexpressionshall
haveintegertype,andtheresulthastype‘‘type’’.
Semantics
2Apostfixexpressionfollowedbyanexpressioninsquarebrackets[]isasubscripted
designationofanelementofanarrayobject.Thedefinitionofthesubscriptoperator[]
isthatE1[E2]isidenticalto(*((E1)+(E2))).Becauseoftheconversionrulesthat
applytothebinary+operator,ifE1isanarrayobject(equivalently,apointertothe
initialelementofanarrayobject)andE2isaninteger,E1[E2]designatestheE2-th
elementofE1(countingfromzero).
加上回答:
我想sizeof(FLASH)存在,&FLASH不存在(未驗(yàn)證)
網(wǎng)友評(píng)論:“取一個(gè)數(shù)組名的地址所產(chǎn)生的是一個(gè)指向該數(shù)組的指針,而不是一個(gè)指向某個(gè)指針常量值的指針。”是你說的那本書里的?
*********************************************************************
LZ題目:
main()
{
inta[5]={1,2,3,4,5};
int*ptr=(int*)(&a+1);
printf("
%d,%d",*(a+1),*(ptr-1));
}
輸出結(jié)果是多少?
請(qǐng)解釋一下原因...
*********************************************************************
以下結(jié)果不是推論出來的,是keilC51編譯結(jié)果。并且符合教本上的概念。
*(a+1)即a[1],就是2。*(ptr-1)就是a[0],即1。
什么教本上的什么概念?
《C和指針》P141:
首先讓我們學(xué)習(xí)一個(gè)概念,它被許多人認(rèn)為是C語言設(shè)計(jì)的一個(gè)缺陷。但是,這個(gè)概念實(shí)際上是以一種相當(dāng)優(yōu)雅的方式把一些完全不同的概念聯(lián)系在一起的。
考慮下面的聲明:
inta[5];
a[1]的類型是整型,那a的類型又是什么?它所表示的又是什么?一個(gè)合乎邏輯的答案是它表示整個(gè)數(shù)組,但事實(shí)并非如此。
........(詳見31樓貼)
只有在兩種場(chǎng)合下,數(shù)組名并不用指針常量來表示:
1、當(dāng)數(shù)組名作為sizeof操作符的操作數(shù)時(shí):sizeof返回整個(gè)數(shù)組的長(zhǎng)度,而不是指向數(shù)組的指針的長(zhǎng)度。
2、當(dāng)數(shù)組名作為單目操作符的操作數(shù)時(shí):取一個(gè)數(shù)組名的地址所產(chǎn)生的是一個(gè)指向該數(shù)組的指針,而不是一個(gè)指向某個(gè)指針常量值的指針。
————摘自《POINTERSONC》KennethA.Reek著
實(shí)驗(yàn)做過了。與KennethA.Reek教本中講述的概念一致:
inta[5];
int*ptr=&a;或者int*ptr=a;都是一樣的。ptr都等于0x22(假定data地址。)
printf("
%#x,%#x",a,ptr);打印結(jié)果:0x22,0x22。
0x22是a[0]的地址&a[0],也是指向a數(shù)組的指針。
請(qǐng)用C51編譯器做一下,看看有沒有警告。是你的問題還是KennethA.Reek教本的問題?
網(wǎng)友評(píng)論:OK,你如果一定認(rèn)為我錯(cuò)了的話就隨便你,當(dāng)然目前看來還沒有人同意我的觀點(diǎn)
另外,如果對(duì)我所說的無法理解的話,還是建議簡(jiǎn)單的認(rèn)為我說的是錯(cuò)的
當(dāng)然,我的理解不會(huì)受到任何影響
int*ptr=&a;或者int*ptr=a;都是一樣的。ptr都等于0x22
我很早就說過了,數(shù)值上是一樣的,類型上不一樣。前提:通過編譯,目前在我使用的編譯器中,還沒有能夠0e0w通過的
0e0w=0error0warning
真的到此位置吧,我認(rèn)為已經(jīng)闡述清楚了
toLX:
看來ISO(theInternationalOrganizationforStandardization)andIEC(the
InternationalElectrotechnicalCommission)干的還不錯(cuò)
也就是說:如果int*p=&a;中&a要+1的話,就需要int*p=(int*)(&a+1);?
最后加上一段(不知道怎么放到簽名位置):
AllwhatIpublishisinthehopethatitwillbeuseful,butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyofMERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.
網(wǎng)友評(píng)論:只是沒有強(qiáng)調(diào)E1是一個(gè)常量指針,——不可改變的值。不具有指針變量的性質(zhì)。
故意寫成int*p=&a+1;不太好吧。看看LZ的寫法。
網(wǎng)友評(píng)論:連生成的匯編代碼都一模一樣,這個(gè)是在VC6下測(cè)試的代碼:
6:unsignedchari[5]={0,1,2,3,4};
00401038movbyteptr[ebp-8],0//由此可知i的地址為epb-8,我這里是一個(gè)臨時(shí)數(shù)組,被分配在棧中,通過ebp變址尋址來訪問
0040103Cmovbyteptr[ebp-7],1
00401040movbyteptr[ebp-6],2
00401044movbyteptr[ebp-5],3
00401048movbyteptr[ebp-4],4
7:unsignedchar*p;
8:p=(char*)(&i);
0040104Cleaeax,[ebp-8]//這是取地址的代碼,指針p的位置在ebp-0C處。
0040104Fmovdwordptr[ebp-0Ch],eax
9:p=i;
00401052leaecx,[ebp-8]//不取地址,生成的代碼完全一樣
00401055movdwordptr[ebp-0Ch],ecx
另外,我改成一個(gè)函數(shù),test2,測(cè)試的結(jié)果也是一樣的,加不加&都一樣。
11:unsignedchar*p;
12:p=(char*)(&test2);
0040108Cmovdwordptr[ebp-0Ch],offset@ILT+0(_test2)(00401005)
13:p=(char*)test2;
00401093movdwordptr[ebp-0Ch],offset@ILT+0(_test2)(00401005)
另外,對(duì)于指針或者數(shù)組,里面的偏移量放前面也無所謂,
unsignedchari[5]={0,1,2,3,4};
unsignedchar*p;
p=i;
3[p]=2
;//非典用法,但工作正常
網(wǎng)友評(píng)論:
其中內(nèi)容未列入隨筆,在此帖出以供參考
數(shù)組實(shí)際上是一個(gè)由分層次疊加構(gòu)造而成的一種數(shù)據(jù)結(jié)構(gòu),其最底層的基礎(chǔ)就是下標(biāo)操作符。作為一種操作符不僅可以和數(shù)組聯(lián)用,還可以通過重載改變其原始語義(具體可見新手版內(nèi)C++隨筆-21)。
只要有了一個(gè)常量指針,配合下標(biāo)操作符的使用,就可以形成一個(gè)數(shù)組的雛形(前提是具備一個(gè)以常量指針為起始點(diǎn)的存儲(chǔ)空間)。當(dāng)然作為數(shù)組的雛形自然有其缺陷,那就是缺少數(shù)組的長(zhǎng)度信息,以至于不可能得到其有效的整體特性。因此作為一個(gè)“完整”的數(shù)組定義還必須加入數(shù)組的長(zhǎng)度信息。但作為一維數(shù)組,相關(guān)定義并未改變其“數(shù)組名”和下標(biāo)操作符的基本屬性。
那么多維數(shù)組情形又將是如何的呢?顯然由于多維數(shù)組必須含有n-1維下標(biāo)長(zhǎng)度的信息(n>1),所以不可能存在上述數(shù)組的原始實(shí)現(xiàn)(僅用起始指針和下標(biāo))。那么多維數(shù)組具體又是如何定義的呢?先列出定義形式:
typeA[N1][N2]...[Nn];
其中n為數(shù)組的維數(shù),N1...Nn為數(shù)組各維的長(zhǎng)度。
類似的,若將A獨(dú)立拿出來看,它還是一個(gè)指向數(shù)組起始位置的常量指針。問題是在此情況下所指對(duì)象的“類型”是什么?是否還能象一維數(shù)組那樣所指類型為數(shù)組單元變量類型呢?顯然不行,因?yàn)檫@樣的話將失去多維數(shù)組中相當(dāng)重要的長(zhǎng)度信息。那么不指向數(shù)組單元變量又指向什么呢?答案是,A將被定義為指向“數(shù)組類型”type[N2]...[Nn]的指針。由此,實(shí)際上還可以得出這樣一個(gè)結(jié)論,數(shù)組A是被組織成N1個(gè)類型為type[N2]...[Nn]的單元的“一維數(shù)組”,其中*(A+i)為此“一維數(shù)組”的第i+1個(gè)單元(即i+1個(gè)數(shù)組的數(shù)組名)。以此類推,可以得到這樣一個(gè)表達(dá)式:
*(...*(*(A+i)+j)+...k)<=>A[j]...[k]
利用這種層次疊加構(gòu)造法,順理成章地建立了從最原始的數(shù)組雛形,通過不斷地增加維長(zhǎng)信息,最終到多維數(shù)組空間的形成機(jī)制。
下面列出一個(gè)具體的實(shí)例:
#include"stdafx.h"
intA[10][20][30];
intx,y;
intmain(intargc,char*argv[])
{
A[1][2][3]=1234;
*(*(*(A+3)+2)+1)=4321;
x=*(*(*(A+1)+2)+3);
y=A[3][2][1];
return0;
}
網(wǎng)友評(píng)論:正方可能是把一維數(shù)組和2維數(shù)組的概念搞混了。正方說“int*pt=a;取地址運(yùn)算后,pt與a數(shù)值相同,類型不同。”再看看教本上怎么說的,《C與指針》P158:
inta[5],*pt=a;
是一個(gè)合法聲明。它為一個(gè)整形數(shù)組a分配內(nèi)存,把pt聲明為一個(gè)指向整型的指針,并把它初始化為指向a數(shù)組的第1個(gè)元素。pt和a具有相同的類型:指向整型的指針。
pt和a均為指向int的指針,類型哪點(diǎn)不同?(不相同的類型可以作為左、右值?)a的類型怎么可能是int[5]?這是2維數(shù)組的概念吧。
正方認(rèn)為,經(jīng)過了int*pt=a;pt就“提升”成為了“指向整型數(shù)組的指針”,一個(gè)指向標(biāo)量的指針pt就提升為了指向矢量的指針!?pt+1就指向了a[6]。
要證實(shí)這個(gè)猜想,很簡(jiǎn)單,由下面程序,運(yùn)行一下,看看結(jié)果就行了:
inta[5]={1,7,3,4,5};
int*pt=a;
intmatrix[3][5];
int(*ptx)[5]=matrix;//指向整型數(shù)組的指針說明。--2維數(shù)組。(怎樣聲
//明一個(gè)指向int數(shù)組的指針?)
intmain()
{
a[4]=*(pt+1);//按照正方的觀點(diǎn),這是絕對(duì)通不過編譯的。(結(jié)果實(shí)際是合法的,它
//將a[1]賦給了a[4]。5被修改為7。)
pt=matrix;//行嗎?
pt=ptx;//行嗎?
}
HWM說得很清楚了,2維數(shù)組matrix中,matrix仍然是一個(gè)常量指針,而*(matrix+i)=matrix依然是常量指針,它指向int數(shù)組而不是指向int標(biāo)量。對(duì)matrix取值操作*matrix將得到一個(gè)int標(biāo)量matrix[0]而不是一個(gè)int數(shù)組向量的值。matrix和pt根本不是相同的類型。
*********************************************************************
正方:
“關(guān)鍵:&a+1是什么意思
&a是取a的地址,結(jié)果是指向a的類型的指針,對(duì)指針的+1是指針+指針指向的類型的長(zhǎng)度
a的類型是int[5],那么&a的操作的結(jié)果是得到一個(gè)指向int[5]類型的指針,……”
反方:
這是很古老的C,還是2維數(shù)組概念用錯(cuò)了地方?
網(wǎng)友評(píng)論:inta[N];
int*p=a;Noproblem
int*p=&a;
這種情況,編譯器應(yīng)該明確的給出一個(gè)錯(cuò)誤,如果不這樣做,應(yīng)當(dāng)被認(rèn)為是編譯器的缺陷。一個(gè)嚴(yán)謹(jǐn)優(yōu)秀的編譯器不應(yīng)當(dāng)出現(xiàn)不恰當(dāng)?shù)钠缫猓悦鈱?dǎo)致不必要的混亂。
網(wǎng)友評(píng)論:我的意思是:&a跟a的類型不一樣,但是值一樣的,它們都是數(shù)組a[]的首地址。
網(wǎng)友評(píng)論:inta[N];
int*p=a;
int*p=&a;
再看看教本是怎么說的:“(第3式中)初始化表達(dá)式中的&操作符是可選的,因?yàn)閿?shù)組名被使用時(shí)總是由編譯器把它轉(zhuǎn)換為數(shù)組指針。&操作符只是顯式地說明了編譯器將隱式執(zhí)行的任務(wù)。”
“初始化表達(dá)式中”,編譯器將&a和a一視同仁,正是它經(jīng)過多重思慮而確定的“優(yōu)雅的處理方法”。最新C編譯器這么做自有它的道理。以前古老的C編譯器正是按照56樓認(rèn)為的“嚴(yán)謹(jǐn)優(yōu)秀”而做的。實(shí)踐中發(fā)現(xiàn)了一些問題,經(jīng)過多重改進(jìn),ANSIC才有了現(xiàn)在這種優(yōu)雅的處理方式。
注意2個(gè)前提條件:
1、是對(duì)待數(shù)組名或函數(shù)名(向量標(biāo)識(shí)符)的處理方式。而不是普通變量(標(biāo)量)名。
2、是在初始化表達(dá)式中,編譯器的處理方式。
要是連這么點(diǎn)前提條件都注意不到就大喊“缺陷”,比ANSIC、Aenneth還高明?
網(wǎng)友評(píng)論:我也就不回復(fù)了,即使你認(rèn)為我說的是錯(cuò)誤的也沒有關(guān)系,但是如果我覺得可能會(huì)引起問題的話,還是講一下的好
我想知道
“(第3式中)初始化表達(dá)式中的&操作符是可選的,因?yàn)閿?shù)組名被使用時(shí)總是由編譯器把它轉(zhuǎn)換為數(shù)組指針。&操作符只是顯式地說明了編譯器將隱式執(zhí)行的任務(wù)。”
是哪本書中的?
按照C99的標(biāo)準(zhǔn)第46頁6.3.2.1的第三條,"arrayoftype"類型作為除sizeof或者&操作符外其他操作符的操作數(shù)時(shí),其類型是"pointertotype"
根據(jù)第四條,函數(shù)明也類似
inta[3];
int*p=a;中,a是"pointertotype"
int*p=&a;中,a是"arrayoftype",而&a是"pointertoarrayoftype",當(dāng)然,有些編譯器可以轉(zhuǎn)化為"pointertotype"使得編譯通過
int*p=&a+1;&a是"pointertoarrayoftype",也就是說指針&a指向的類型是"arrayoftype",以上例子中這個(gè)類型的長(zhǎng)度為3*sizeof(int),而指針+n是“指針的值+n*sizeof(指針指向的類型)”,所以&a+1的值應(yīng)該是&a[0]+1*(3*sizeof(int))
如果&a和a是一樣的話,那么:
int*p=&a+1;
int*p=a+1;
p在數(shù)值上都應(yīng)該是一樣的(&a[1]),不過目前只聽00說Keil上是一樣的,不知道還有哪些編譯器上也是一樣的
網(wǎng)友評(píng)論:有時(shí)甚至是非法地址,因?yàn)樵L問存在對(duì)齊的問題
網(wǎng)友評(píng)論:沒有任何人聲稱比ANSIC、Aenneth還高明,進(jìn)一步說,ansic被公認(rèn)有缺陷,但并無損ansic的地位,畢竟制定者是人,不是神。請(qǐng)就事論事!
"編譯器將&a和a一視同仁",這種聲稱是不恰當(dāng)?shù)模辽賤c2005下,會(huì)給出一個(gè)錯(cuò)誤。某一compiler沒有給出一個(gè)錯(cuò)誤,應(yīng)當(dāng)是一個(gè)缺陷,道理已經(jīng)說的很明白了,如果再扯到“高明“上去,純屬人品問題。
網(wǎng)友評(píng)論:在CodeVisionAVR下,p=(int*)(&a);提示說非法地址:illegaladdress。這個(gè)就無法驗(yàn)證了。
在CARM編譯器下,&a+1跟a+1的值不一樣。
在RealView編譯器下,&a+1跟a+1的值也不一樣。
網(wǎng)友評(píng)論:
看一下這個(gè)式子是否能撥開迷霧:
*(...*(*(A))...)<=>A[0][0]...[0]
其中從A到*(...*(*(A))...)全都是常量指針(也可叫數(shù)組名),他們所指的“類型”分別是
A->type[N2]...[Nn]
...
*(...*(*(A))...)->type
而其所指地址就是A的“首地址”。
現(xiàn)在再來看&A是個(gè)什么玩意兒。它是由A為單元的一個(gè)更高層次的數(shù)組名(別名為常量指針),由上類推可以得出其所指類型為type[N1][N2]...[Nn]。但問題是這個(gè)所謂的數(shù)組根本就沒有定義,因此某種程度上可以認(rèn)為&A是一個(gè)杜撰出來的玩意兒,沒有意義。所以才會(huì)出現(xiàn)不同的編譯器對(duì)&A會(huì)有不同的處理,這一點(diǎn)都不奇怪,雖然在C標(biāo)準(zhǔn)中對(duì)&A有相應(yīng)的規(guī)定。也許C標(biāo)準(zhǔn)是認(rèn)為存在一個(gè)未定義的數(shù)組type[1][N1][N2]...[Nn]作為其&A的拓廣。
網(wǎng)友評(píng)論:to60樓
只是想根據(jù)標(biāo)準(zhǔn)作個(gè)簡(jiǎn)單的說明
所以都用int類型,一般int類型比較不容易出現(xiàn)你說的這些問題,可能LZ出題的時(shí)候也考慮到了
另外,和大小端有關(guān)就不是很理解了,是否小端中使用a[1]的話,大端中使用a[-1]?這個(gè)不是由編譯器搞定的么?
to63樓
謝謝LS講解,其實(shí)n數(shù)組可以簡(jiǎn)單的當(dāng)作類型為n-1維數(shù)組的1維數(shù)組來理解,所以沒有必要把問題復(fù)雜話
toall
inta[3];
認(rèn)為a是int[3]類型,除&和sizeof之外,其他運(yùn)算退化為int*
或者認(rèn)為a是int*類型,在&和sizeof下,有特殊的運(yùn)算方式
我都不認(rèn)為錯(cuò),實(shí)際使用上,這2種理解得到同樣的結(jié)果
但如果說a和&a是等價(jià)的,那么我確實(shí)要說些什么了
網(wǎng)友評(píng)論:
附:數(shù)組的定義
數(shù)組是由一個(gè)指向首單元的常量指針(數(shù)組名)所引領(lǐng)的一組一定數(shù)量的連續(xù)單元所組成的數(shù)據(jù)結(jié)構(gòu)。此常量指針的尺寸大小(尺寸的拓廣)定義為整個(gè)數(shù)組的大小。此常量指針的地址(地址的拓廣)定義為數(shù)組首單元的地址。多維數(shù)組typeA[N1][N2]...[Nn]定義為一個(gè)常量指針(數(shù)組名)為A,由N1個(gè)單元(類型為type[N2]...[Nn],數(shù)組名為*(A+i)的數(shù)組,i=0...N1-1)組成的一維數(shù)組。這里的單元要理解成相關(guān)數(shù)組的常量指針(數(shù)組名)。
由以上數(shù)組的定義可以對(duì)實(shí)例中的相關(guān)表達(dá)式作以下分析:
*(*(*(A+1)+2)+3)
先看A,它是一個(gè)指向數(shù)組首單元(類型為int[20][30])的常量指針(此單元為*A)。那么*(A+1)就是指向第二個(gè)單元(第二個(gè)類型為int[20][30]的數(shù)組的常量指針)。然后在此數(shù)組(常量指針或數(shù)組名為*(A+1))內(nèi)再得到類型為int[30]的第三個(gè)數(shù)組的常量指針*(*(A+1)+2)。最后在這個(gè)數(shù)組(常量指針或數(shù)組名為*(*(A+1)+2))中指定類型為int的第四個(gè)單元*(*(*(A+1)+2)+3),即數(shù)組A的單元變量A[1][2][3]。
用地址算式可以表示如下
*((int*)A+(1*sizeof(*(A))+2*sizeof(*(*(A)))+3*sizeof(*(*(*(A)))))/sizeof(int))
其中
*(A+1)的地址為(int*)A+1*sizeof(*(A))/sizeof(int)
*(*(A+1)+2)的地址為(int*)A+(1*sizeof(*(A))+2*sizeof(*(*(A))))/sizeof(int)
*(*(*(A+1)+2)+3)的地址為(int*)A+(1*sizeof(*(A))+2*sizeof(*(*(A)))+3*sizeof(*(*(*(A)))))/sizeof(int)
網(wǎng)友評(píng)論:另一個(gè)例子是函數(shù)指針賦值,我推測(cè)compiler設(shè)計(jì)者對(duì)此類問題作過推敲:使用&的程序員絕對(duì)不會(huì)是想對(duì)數(shù)組首址或函數(shù)地址再取地址(因?yàn)槟菦]有意義,數(shù)組名是被compiler當(dāng)作數(shù)組首址,一般來說是一個(gè)常數(shù)),而是想獲取數(shù)組名或函數(shù)名的地址,故而使用&.對(duì)用戶接口設(shè)計(jì)有經(jīng)驗(yàn)的人經(jīng)常會(huì)遇到此類問題,你知道用戶意圖,但是否放寬容錯(cuò)度則很難抉擇。
看看visualC,到了2005,語法嚴(yán)格很多,以前可以編譯通過的程序會(huì)給出很多錯(cuò)誤,以至于我們這里的程序員不愿意升級(jí)。我個(gè)人認(rèn)為ms做得對(duì):被通過的缺陷比沒通過要可怕很多,這會(huì)直接或間接鼓勵(lì)犯錯(cuò)。
網(wǎng)友評(píng)論:看看教材是怎樣說的:《C與指針》P258
——只有當(dāng)確實(shí)需要時(shí),你才應(yīng)該使用多層間接訪問。不然的話,你的程序?qū)?huì)變得更龐大、更緩慢并且難于維護(hù)。
編譯器的差別:
...編譯器對(duì)表達(dá)式…,你是不是覺得它有點(diǎn)笨?…是的。這個(gè)編譯器確實(shí)有點(diǎn)舊,它的優(yōu)化器也不是很聰明。現(xiàn)代的編譯器可能會(huì)表現(xiàn)的好一點(diǎn),但也未必。和那些編寫差勁的源代碼,然后依賴編譯器去產(chǎn)生高效的目標(biāo)代碼相比,直接編寫良好的源代碼顯然更好。……
網(wǎng)友評(píng)論:換了個(gè)編譯器測(cè)試下,更暈,結(jié)果發(fā)現(xiàn)&a是不允許的……
在CodeVisionAVR下,p=(int*)(&a);提示說非法地址:illegaladdress。這個(gè)就無法驗(yàn)證了。
在CARM編譯器下,&a+1跟a+1的值不一樣。
在RealView編譯器下,&a+1跟a+1的值也不一樣。
網(wǎng)友評(píng)論:&a和a都表示a[]的首地址。
&a+1和a+1,目前只有在keil51下測(cè)試相等,其它測(cè)試不相等~~~~有的干脆編譯通不過~~~
所以還是別搞&a這樣的東西為妙~~~~~~
網(wǎng)友評(píng)論:這里有一個(gè)比喻:
我在六里橋,想到西客站。這是兩條背靠背的公交線,中間沒有公交路。但是可以穿胡同走過去,直線距離200米,步行不要5分鐘。如果乘坐公交車,就要繞一個(gè)大彎,大概2公里。10倍距離!
穿胡同我不認(rèn)得路,于是決定打的。上車后跟司機(jī)說:“去西客站。”多說了一句廢話:“走公交線。”(&a)
這時(shí)的出租車司機(jī)有3種選擇:
1、載上我,穿胡同,不到半分鐘,10元錢到手。這就是C51編譯器的做法,立即尋址。3種選擇里以高效為原則。(a)
2、拒載。司機(jī)覺得走公交線繞遠(yuǎn)劃不來,2公里也是10元。這就是有些編譯器拒絕p=&a;的做法:“你的要求我無法實(shí)現(xiàn)。”。“請(qǐng)下車,自己走過去,很近。”(拒絕編譯)
3、司機(jī)就按我的要求,繞一個(gè)大彎到西客站。低效就低效,不賺錢就不賺錢。一切服從客戶。這就是正方所希望的編譯器優(yōu)秀而的功能。“我沒讓你立即尋址,我讓你間接尋址你就間接尋址,別太裝聰明了。”
*(*(&(&
看看教材是怎樣說的:《C與指針》P258
——只有當(dāng)確實(shí)需要時(shí),你才應(yīng)該使用多層間接訪問。不然的話,你的程序?qū)?huì)變得更龐大、更緩慢并且難于維護(hù)。
間接尋址的最終目的是什么?在這里除了獲得數(shù)組a某個(gè)位置的值a外還能有什么?顯然,一個(gè)數(shù)組名a表示&a[0],如果為了訪問a的值,一定要通過&&a[0]去達(dá)到目的,它是“確實(shí)需要”的么?現(xiàn)代編譯器會(huì)識(shí)別出用戶的問題,要么拒載,要么自動(dòng)選擇1、直接尋址方式a幫你取得那個(gè)位置的值。就是不可能選擇方式3,繞個(gè)大圈去取得a的值,結(jié)果導(dǎo)致你的程序比別人龐大10倍,甚至無法運(yùn)行。它不至于那么笨,看不出有優(yōu)化捷徑。
我想現(xiàn)代編譯器的工作方式是:即使按方式3操作,最后通過優(yōu)化器,還是回到了方式1、立即尋址或直接尋址方式。
網(wǎng)友評(píng)論:在c/c++中,真正意義上的多維數(shù)組是不存在的,多數(shù)compiler內(nèi)部還是一維,因?yàn)閏ompiler知道各維大小,因而可以計(jì)算出各個(gè)元素的具體偏移。一旦沒有了上下文,比如多維數(shù)組作為指針變量被傳遞,compiler就無法使用多維數(shù)組,這也就是很多compiler對(duì)多維數(shù)組轉(zhuǎn)換為指針加以限制的原因。
其他一些語言,比如java,c#,多維數(shù)組有所不同,生成與堆上而不是棧上,可以認(rèn)為真正意義上的多維數(shù)組,比如二維,是必須先生成一個(gè)直指針數(shù)組,用以存儲(chǔ)下一維各個(gè)數(shù)組的首址。
網(wǎng)友評(píng)論:在數(shù)組的定義中其實(shí)已經(jīng)引入了指針概念,只是為了存儲(chǔ)和訪問的效率起見未將指針實(shí)體化(僅以概念化的常量指針的方式出現(xiàn))。所以作為常量指針的“數(shù)組名”只能出現(xiàn)在表達(dá)式中,卻不可以作為實(shí)體承接數(shù)值。
個(gè)人認(rèn)為,C/C++中關(guān)于數(shù)組的定義過于松散。這不僅表現(xiàn)在其類型定義上,還體現(xiàn)在其組成結(jié)構(gòu)上。正因?yàn)閿?shù)組名被定義為一個(gè)常量指針,卻又并非指向數(shù)組整體,所以使得數(shù)組看起來象是一串珍珠,一旦斷線就散落一地。
網(wǎng)友評(píng)論:匯編程序中經(jīng)常用到查表方法。一組連續(xù)的相同類型數(shù)據(jù),表首地址有一個(gè)標(biāo)號(hào)TABLE:...數(shù)據(jù)聚合。基址MOVDPTR,#TABLE加偏移A間接尋址方式被用來獲得這個(gè)表中一個(gè)位置的數(shù)據(jù)——MOVCA,@A+DPTR。
映像到C是完全一樣的!例如:現(xiàn)有數(shù)組charTABLE[10];C程序中寫下DPTR=TABLE;編譯后的匯編語句為立即尋址方式:MOVDPTR,#TABLE。C語句ACC=TABLE[2];編譯為間接尋址MOVCA,@A+DPTR。
要是想知道匯編程序中TABLE標(biāo)號(hào)的地址在哪里,是不是有點(diǎn)開玩笑?“它可能在哪里?”它除了標(biāo)識(shí)這張表,標(biāo)識(shí)它的內(nèi)存固定位置之外,它有地址么?匯編語言中TABLE的值怎么可能表示這個(gè)表中分立的10個(gè)字節(jié)的數(shù)據(jù)?有意義?
網(wǎng)友評(píng)論:對(duì)于那些人為定義的東西只能死記硬背了!!
網(wǎng)友評(píng)論:不知道高手們?yōu)槭裁聪矚g用有歧義的東西呢,想讓他們輸出什么多一條語句不就好了嗎?
網(wǎng)友評(píng)論:ptr的地址就是指向a[1],所以ptr-1就是a[0]=1
網(wǎng)友評(píng)論:
呵呵,大家都說完了嗎?本姑娘也來說幾句。
1、數(shù)組就是數(shù)組,函數(shù)就是函數(shù),指針就是指針。
2、只有在需要對(duì)表達(dá)式求值時(shí)編譯器才會(huì)將數(shù)組名和函數(shù)名轉(zhuǎn)換為指針。
例如:通常情況下編譯器不需要對(duì)sizeof、& 的表達(dá)式進(jìn)行求值即可確定操作結(jié)果,所以在這里數(shù)組名和函數(shù)名不會(huì)被轉(zhuǎn)換為指針。
3、標(biāo)準(zhǔn)C和傳統(tǒng)C對(duì)取地址運(yùn)算符& 的解釋不同。
如果a是某種類型的數(shù)組,&a 的類型是該類型數(shù)組的指針,而傳統(tǒng)C則把&a當(dāng)成a
4、大家不覺得 computer00 很可愛嗎?
computer00 是偶最喜歡的版主
上面第2點(diǎn)偶曾求證過GNU的Richard Stallman先生,Richard Stallman先生的回答很幽默,大意是:“當(dāng)然。如果是你做編譯器,你也會(huì)這么干!”
網(wǎng)友評(píng)論:哇塞,LS mm來頭大。
網(wǎng)友評(píng)論:哇塞,LS mm來頭大。
mcuisp 發(fā)表于 2009-9-13 12:39
俺可不是大頭MM哦
大頭很難看滴
網(wǎng)友評(píng)論:知道了,LS是很漂亮的mm
名字就很美。
不知道是見面不如聞名呢?還是聞名不如見面
網(wǎng)友評(píng)論:書上的題目了1
網(wǎng)友評(píng)論:知道了,LS是很漂亮的mm
名字就很美。
不知道是見面不如聞名呢?還是聞名不如見面
mcuisp 發(fā)表于 2009-9-13 14:26
人如其名也,
聞名如見面。
網(wǎng)友評(píng)論:個(gè)人覺得, 正規(guī)的開發(fā)人員 ( 而不是玩技術(shù)的 ) 應(yīng)該避開這些缺陷, 對(duì)于花哨玩意兒, 簡(jiǎn)單弱智點(diǎn)好. 完全可以參考 C++ 甚至 Java 的某些風(fēng)格去寫程序, 這些語言的一些規(guī)定其實(shí)也是在逐步修正 C 的問題.
網(wǎng)友評(píng)論:熱烈贊同樓上的說法!!!
對(duì)于這種繞腦筋的題,我現(xiàn)在懶得去看了。
實(shí)在有需要,用編譯器來實(shí)驗(yàn),呵呵。
網(wǎng)友評(píng)論:哈哈,這么熱鬧,原來是來了一位女俠.
網(wǎng)友評(píng)論:我覺得11樓的這個(gè)問題很明確,
網(wǎng)友評(píng)論:*(&cB) = *(&cA); // error, why?
cB和cA是一個(gè)常量,就是數(shù)據(jù)第一個(gè)元素的地址,所以你對(duì)一個(gè)常量取地址是錯(cuò)誤的。例如你寫成這樣:&5一樣
網(wǎng)友評(píng)論:#include "stdafx.h"
char cA[10];
char cB[10];
int main(int argc, char* argv[])
{
*(&cB) = *(&cA); // error, why?
// 編譯器對(duì) (&cA) 和 (&cB) 求值,得到指向“包含10個(gè)char類型元素的數(shù)組類型”的指針,即char (*)[10] ,隨后編譯器對(duì) char (*)[10] 解引用,結(jié)果類型為“包含10個(gè)char類型元素的數(shù)組類型”。而數(shù)組是不能整體賦值的,所以產(chǎn)生語法錯(cuò)誤。
*(cB) = *(cA); // ok
*(&cB[0]) = *(&cA[0]); // ok
// 上面兩種情況是一回事,編譯器將把數(shù)組名cA和cB轉(zhuǎn)換為指向數(shù)組首對(duì)象的指針,即 (char *) 。(注意:是“首對(duì)象”而不是“首地址” ,對(duì)C數(shù)組而言首對(duì)象就是數(shù)組的第一個(gè)元素,即cA[0] 和 cB[0] ,它們的類型是char)。隨后編譯器對(duì) (&cA[0]) 和 (&cB[0]) 解引用,結(jié)果類型為“char類型”,并且是個(gè)可修改的左值。這是兩條合法的C語句。
return 0;
}
網(wǎng)友評(píng)論:這涉及C編譯器怎么處理左值與右值的規(guī)定;還有就是編譯器只不能訪問一個(gè)地址開始的整體,只能逐一訪問整體中的單個(gè)地址。對(duì)*(&cB)的操作代表的是一個(gè)整體的操作,對(duì)*(cB)的操作是對(duì)一個(gè)地址的操作。
網(wǎng)友評(píng)論:編程語言可以看成是編譯器的生產(chǎn)者與使用者之間的協(xié)議
既然是協(xié)議,當(dāng)然要盡量公平呀,語言的制定者需要兼顧各方的利益
一些語法規(guī)則在使用者看來是“不合理”甚至“缺陷”,但編譯器卻喜歡
所以理解編譯器的實(shí)現(xiàn)非常有助于理解語言的內(nèi)涵