C++,那些可爱的小陷阱(二)
這一次,是關(guān)于聲明的一個(gè)小問題:
?
#include?<stdio.h>?int?j?=?24;?
int?main()?
{?
????int?i?=?j,?j;?
????j?=?42;?
????printf("%d?%d\n",?i,?j);?
}
?
這能通過編譯嗎?能
這不會(huì)產(chǎn)生未定義行為嗎?不會(huì)
這程序甚至不是ill-formed(ill-formed就是C++支持但不推薦的寫法),
輸出的結(jié)果是:
24 42
這個(gè)問題并不難猜到答案,但是大概大部分同學(xué)都不敢很肯定地說出來。我們來看看標(biāo)準(zhǔn)如何解釋的這個(gè)問題:
j這個(gè)名字被聲明了兩次(也使用了兩次),第一個(gè)j聲明的區(qū)域涵蓋了整個(gè)例子,第一個(gè)j的潛在可用域從這個(gè)j的后面立刻開始一直延伸到程序結(jié)束,但是它(實(shí)際上)的作用域不包括,和}之間的文本。第二個(gè)j聲明的區(qū)域包括{和}之間的所有文本,但是它的潛在可用域不包括i的聲明。第二個(gè)j聲明的實(shí)際作用域和潛在可用域是相同的。 下面我補(bǔ)了一張圖,藍(lán)色部分就是第二個(gè)j的實(shí)際作用域。
int j = 24;
int main()
{
??? int i = j, j;
??? j = 42;
??? printf("%d %d\n", i, j);
}
從上面看出C++聲明精確地從聲明的點(diǎn)開始有效,但是還有一些特別要注意的地方,這里又有幾條C++標(biāo)準(zhǔn)中的小例子,猜猜它們的結(jié)果:
?
int?x?=?12;?{?int?x?=?x;?}
?
const?int?i?=?2;?{?int?i[i];?}
?
const?int?x?=?12;?{?enum?{?x?=?x?};?}
?
?
struct?X?{
????enum?E?{?z?=?16?};
????int?b[X::z];
};
?
答案:
1.第二個(gè)x被以它自己的值初始化,變量聲明在初始化之前生效。
2.數(shù)組i被正確初始成大小2,外層變量直到聲明的那一點(diǎn),都是可見的。
3.enum中的x被正確初始化為12,枚舉類型的聲明點(diǎn)緊接它的定義之后(也就是,枚舉類型聲明位于聲明生效點(diǎn)之前。)。
4.數(shù)組b被正確初始化為大小16,一個(gè)類成員的定義點(diǎn)之后,類的域中就能查找到這個(gè)名字。
?
That’s all, thanks.
from: http://www.cnblogs.com/winter-cn/archive/2009/11/18/1605662.html
總結(jié)
以上是生活随笔為你收集整理的C++,那些可爱的小陷阱(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试时算法题的解答思路
- 下一篇: C++,那些可爱的小陷阱(三)