1)答案為: a
note1:求值順序是自右至左;輸出順序還是從左至右.
note2: 如果把printf(「%d %d\n」, *ptr, *(++ptr) );換成printf(「%d %d\n」, *ptr, *(ptr++) );結果為c,雖然求值是從右向左的,但是表示式中的*ptr與*(ptr++)不是兩個語句,所以ptr的值相同
2) (int&)a 與 (int)&a 及(int)a有什麼區別
#include
using namespace std;
void main()
note1:
(int&)a 把a強制轉換成整形引用型別不經過轉換, 直接得到a在記憶體單元的值
(int)a 把a強制轉化為整型經過轉換了
(int)&a 把a的位址強制轉換成整型
note2:
float型別在記憶體中儲存的形式是 ,符號位指數尾數
由754標準:階碼採用增碼(該數補碼的反符號),尾數採用原碼
所以1.0f 在記憶體中的形式為
0011 1111 1000 0000 0000 0000 0000 0000符號位指數尾數
0000 0001 //原始碼
1111 1110+1=1111 1111//補碼=>取反加1
0111 1111//增碼=> 符號取反
所以輸出的是 0x3f800000
0 在記憶體中的的儲存形式
0000 0000 0000 0000 0000 0000 0000 0000
3) 單目 > 算數 > 移位( << >>) >關係( > >= < <> 邏輯
note1: 運算子的優先順序,所以是先對a求反,然後再右移5位
note2: 型別轉換,a會先被提公升到int型進行運算,最後取低8位
答案: c
4) 通過位運算求x與y的平均值
解析:(x&y)+((x^y)>>1)是用來求x和y的平均數的,即(x+y)/2.
(x&y)+((x^y)>>1),把x和y裡對應的每一位(指二進位制位)都分成三類,每一類分別計算平均值,最後彙總。其中,一類是x,y對應位都是1,用x&y計算其平均值;一類是x,y中對應位有且只有一位是1,用(x^y)>>1計算其平均值;還有一另是x,y中對應位均為0,無須計算。
下面分別說明一下前兩種情況是怎樣計算的:
x,y對應位均為1,相加後再除以2還是原來的數,如兩個***相加後除以2仍得00001111,這是第一部分。第二部分,對應位有且只有一位為1,用「異或」運算提取出來,然後》1(右移一位,相當於除以2),即到到第二部分的平均值。第三部分,對應位均為零,因為相加後再除以二還是0,所以不用計算。
三部分彙總之後就是(x&y)+((x^y)>>1)
順便解釋一下前面說到可以避免溢位。假設x,y均為unsigned char型資料(0~255,占用一位元組),顯然,x,y的平均數也在0~255之間,但如果直接x+y可能會使結果大於255,這就產生溢位,雖然最終結果在255之內,但過程中需要額外處理溢位的那一位,在彙編中就需要考慮這種高位溢位的情況,如果(x&y)+((x^y)>>1)計算則不會。
5) 通過位運算交換a與b的值
a=a^b; b=a^b; a=a^b; //無需擔心越界問題
6) c語言不支援函式過載
7) 巨集中的引數要注意加括號
答案:#define min(a,b) ( (a)<=(b) ? (a):(b) )
8) const相關說明
a. const與#define:作用域,有型別,方便除錯(c中只能用#define表示常量)
b. c與c++中的const
a) c中const的意思是」乙個不能被改變的普通變數」,所以下面的語句是錯誤的
const buffersize=100;
char buf[buffersize];//錯誤,buffersize不是常量
b) c中const預設是外部鏈結的,所以可以有如下的語句
const buffersize; //c認為它是乙個宣告,定義及初始化在其他地方了
而在c++中如果要做同樣的事情需要如下的語句
extern const buffersize; //c++預設const是內部鏈結的
c. c++中的const
void f() const如果想修改類中的非const變數,需要在該變數前加mutable(如mutable int i)
void f()與上面的函式過載
9) sizeof問題之資料對齊
a. char q2=」a\n」;
sizeof(q2); //應該為3
b. struct a;
sizeof(a); //6 short為2
c. struct b;
sizeof(b); //8 long為4
d. class d
sizeof(d); //4 sizeof計算棧中分配的大小,靜態變數是存放在全域性資料區的
e. class e
sizeof(e); //24 怎麼回事呢?????
note:
結構體預設的位元組對齊一般滿足三個準則:
1) 結構體變數的首位址能夠被其最寬基本型別成員的大小所整除;
2) 結構體每個成員相對於結構體首位址的偏移量(offset)都是成員自身大小的整數倍,如有需要編譯器會在成員之間加上填充位元組(internal adding);
3) 結構體的總大小為結構體最寬基本型別成員大小的整數倍,如有需要編譯器會在最末乙個成員之後加上填充位元組(trailing padding)。
10) sizeof小結
a. 對函式使用sizeof, 在編譯階段會被函式返回值的型別替代
例如: int fun(); sizeof( fun() )等同於sizeof( int )
b. sizeof不是函式也不是一元運算子,它是類似於巨集定義的特殊關鍵字,sizeof() 括號內的內容在編譯過程是不會被編譯的,而是被型別替代
int a=8;
sizeof( a=6 ); //結果等同於sizeof(int), 而且執行完a的值仍然是8,因為括號內的內容不會被編譯
11) sizeof與類
a. 空類所佔的空間為1,多重繼承的空類所佔的空間為1
b. 含有虛函式的類空間要加4
12) 常見錯誤1:使用前一定要將指標指向一塊記憶體
錯誤1:
int *pa;
*pa=5; //錯誤,pa還沒指向一塊記憶體
錯誤2:
該函式不能達到交換兩個數的效果,因為temp沒指向一塊記憶體就賦值了
13) 常見錯誤2:傳值與傳址
程式執行時會崩潰,str一直都是null,因為是傳值呼叫的
14) 類中的相對偏移問題
解析:b *pb=(b*)(&a); //強制將a位址的內容轉化為乙個指向b型別的指標
由於int m_a與int m_c的記憶體偏移量相同
所以,本體的答案為1
15) 各種指標,函式指標,陣列指標,指標陣列
16) 指標之間的強制轉換
問題1:
答案: 2 5
解析: &a:型別為int (*)[5],加1則整體加一行,&a+1指向陣列中5的後面
int *ptr=(int*)(&a+1):通過指標之間的強制轉換將&a+1(int (*)[5])轉化成(int*)
ptr-1:ptr是普通的指向int的指標,ptr-1指向陣列中的5
問題2:
int a[4]=;
char *pt=(char*)&a; //等價於char *pt=(char*)&a;
printf("%d %d",*(a+1),*(int*)(pt+4))
答案:2 2
解析:pt為指向陣列a首元素的char型指標,pt+4移動4個位元組
問題3:
巨集定義求結構體內變數的偏移(注意:不能以分號結束)
解析: ->的優先順序大於(type)的優先順序,所以要 ( (struc*)0 ) -> e
note:
a. 指標是什麼呢?一句話,指標其實就是位址。
只要有了乙個位址,就可以訪問到特定的記憶體。這就是指標。因為用途不同(可能指向乙個int啊,也可能指向乙個double啊),所以指標也分很多種。
這些指標本質上都是一樣的(都是記憶體的位址嘛),如果指向乙個地方,那麼值也是一樣的(同乙個地方的位址自然只有乙個咯)。可以通過強制轉換將一塊記憶體轉換成各種型別的指標
b. 如何將乙個指標強制轉化為指向陣列的指標
typedef int (*p)[3];
int(*ap)[3]=(p)ip; //這樣
int(*ap)[3]=(int(*)[3])ip;//或這樣
typedef int (*p)[3];
int(*ap)[3];
ap=(p)ip; //這樣
ap=(int(*)[3])ip;//或這樣
c. 指標強制轉換後的結果是臨時變數,不能作為左值
17) malloc/free與new/delete的區別
18) 智慧型指標
答案: b e
note: b,c格式不對, d是錯的,因為auto_ptr放在vector中是不合理的,
19) 深拷貝與淺拷問題
解析:a. vector *a1=new vector();
a1->push_back(d1); //會呼叫cdemo的預設拷貝建構函式,傳值呼叫時會呼叫拷貝建構函式進行形參與實參的賦值
b. delete a1; //釋放vector物件,vector所包含的所有元素也同時被釋放
c. 區域性變數cdemo d1在main函式退出時,也會釋放所佔的記憶體空間
d. 這樣str所指向的記憶體空間就會被釋放兩次了,引起記憶體錯誤
e. 採用深拷貝可以解決問題
20) 泛型程式設計1 template
21) 泛型程式設計2 函式指標
方法1:使用函式指標
方法2:使用靜態模板類
程式設計師面試寶典 讀書筆記
程式設計師面試寶典 第十章物件導向 1.面向技術的基本概念 物件,類和繼承 2.c 的空類預設產生哪些類成員?預設建構函式,析構函式,拷貝建構函式和賦值函式。3.structure是否可以擁有constructor和destructor及成員函式?如果可以,structure和class還有什麼區別...
程式設計師面試寶典
微軟公司讓應聘者發狂的創意測試 如果你有乙個許多部件可以拆卸的時鐘,你將它一塊塊拆開,但是沒有記住是怎樣拆的。然後你將各個零件重新組裝起來,最後發現有三個重要零件沒有放進去。這時你如何重新組裝這個時鐘?如果你需要學習一門新的計算機語言,你會怎樣做?假設由你負責設計比爾 蓋茨的衛生間。當然,錢不成問題...
程式設計師面試寶典題目總結
1.what will be the output of the following c code?include int main int argc,char argv int ptr arr ptr 123 printf d,d n ptr,ptr return 0 2.下面程式的結果是多少?i...