- 相關推薦
青牛軟件筆試經驗
青牛軟件筆試經驗分享:
1 第一個
void main()
{
int a[5] = {1,2,3,4,5};
int *ptr = (int *)(&a + 1);
int *ptr2 = a+1;
printf("%d,%d,%d\n", *(a+1), *(ptr-1), *(ptr2-1));
}
輸出為2,5,1
問題:中間那個5是怎么來的?
解答:北郵論壇提供
int a[5] = {1,2,3,4,5};
此語句會讓系統在棧內存中分配5個連續的int型(32位機是四個字節)空間
a是一個指針常量,a應該是被分配在靜態存儲區(不敢肯定,望大牛解惑 當然不是,是存在?臻g的動態存儲的,這我自己知道),并且有一個固定的值
假設該數組的首地址為4000,即a的值是4000,那麼數組元素5的地址應該是&a[4] = 4000+4*4 = 4016
另外假設a的地址是3000
int *ptr = (int *)(&a + 1);
指針做加法時,我們要關心的不是指針本身,而是指針所指向的數據類型
很明顯&a是一個指針(指針和地址的概念是等價的,若對這句話有異議,我們可以一起討論),這個指針所指向的是a
而a是一個數組類型(注意,這里不能將a理解為一個指針常量,數組和指針的區別還是很大的),sizeof(a) = 20
所以 ptr = &a+1 = 3000+20 = 3020,在將其轉換為int*型
所以ptr-1 = 3020 - 4 = 3016, 這片內存中的數是不確定的, 所以第二個打印出來5完全是碰巧的,要不就是編譯器的問題
樓主是不是這樣想的?其實這還是搞混了數組和指針
記住,數組就是數組,指針就是指針,千萬不要混用(雖然有時候混用是正確的). 只有當數組以實參傳遞給函數時,它才會變成指針。
這道題我們應該這樣理解:
a是一個int[5]型的數組,那么&a自然是指向這個數組(千萬不要以為&a指向一個指針常量,這就是上面所犯的錯誤),那么&a+1自然是指向下一個數組
所以 ptr = 4000 + 20 = 4020 , 而不是3016。
第二題
void main()
{
char a[][3] = {'1','2','3','4','5'};
cout<<a[0]<<endl;
}
輸出為12345
問題:a[1][2]為啥是0,而不是隨機值?
這個我自己解釋:
此題中 a[][3] 與 a[2][3]是等價的,系統會自動不上一個'\0'(控制字符)如果輸出a[1][2]不會輸出數值0,因為0
對應字符是(null)這個控制字符,因此會啥也不輸出,只是一個空格
a[0]代表了字符數組(字符串)的首地址,大家都知道如果用cout輸出一個字符串名字(也即首地址)會輸出該字符串的內容,因此cout<<a[0]實際上輸出的是a這個字符串的內容12345,而如果輸出a[1]將輸出45
三、
class cls
{
public:
virtual void func1(){}
virtual void func2 (){}
void func3(){}
protected:
private:
static char m_data;};
int main()
{cout<<sizeof(cls)<<endl;
system( "pause ");
return 0; }
輸出4 理由:static變量占用的是靜態區內存而cls占用的是動態區,因此不含有char m_data的內存, func3函數是不占用內存的(不管是否在類內實現還是在類外實現,也不管是否有參數和返回值),實際上cls的內存只有分配了一個虛擬函數表的地址,用來管理虛擬函數的,不論加入多少虛擬函數都只有4個字節的大小,如果把static去掉,那將輸出8,而不是5,這跟struct的內存對齊是一個道理的。
但當類是空類是,只占有1個字節,這大概是系統至少要給類分配一個最小空間以便讓系統知道有該類的存在。
更多相關的文章推薦,大家敬請關注筆試經驗頻道!
【青牛軟件筆試經驗】相關文章:
回憶青牛的筆試題,試題分享02-25
康佳集團杭州軟件類筆試經驗02-10
文思創新軟件技術類筆試經驗12-13
康佳軟件杭州筆試經驗分享 ZZ08-10
筆試經驗:筆試內容準備11-21
軟件筆試題11-06
保利筆試經驗07-06
金地筆試經驗07-06
MTR筆試經驗12-08
中興筆試經驗12-10