int main(void)
{
printf("%s , %5.3s\n","computer","computer");
return 0;
}
輸出
computer , com
%m.ns 輸出佔m列,但只取字符串中左端n個字符。這n個字符輸出在m列的右側,左補空格。
2、
虛函數動態綁定
動態聯編就是程序在運行的時候知道該調用哪個函數,而不是編譯階段,所以這個機制應該是由虛函數支持的,即運行時的多態,基類的某個成員函數聲明爲虛函數,派生類繼承,而且同樣重寫該函數,那麼當聲明一個派生類的指針或者引用時,它所調用的函數是由該指針指向的對象確定的,這就是動態聯編
3、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class parent
{
public :
virtual void output();
};
void parent::output()
{
printf( "parent!" );
}
class son
: public parent
{
public :
virtual void output();
};
void son::output()
{
printf( "son!" );
} |
1 2 3 4 | son
s; memset(&s
, 0 ,
sizeof(s)); parent&
p = s; p.output(); |
沒有輸出結果,程序運行出錯
4、
C++ 類佔用空間計算方式
1、一個類佔用的空間主要是屬性佔用空間,而成員函數一般不佔用空間,但是虛函數佔用空間,需要說明的是,無論多少個虛函數,只要佔用4個字節即可,也就是索引指向一個虛擬表的首位置。另外需要說明的是佔用空間都考慮了對齊,所以不足4個的按照滿4個的算。
2、類的繼承,子類佔用空間是父類基礎上增加本類空間即可。所以說可以認爲,子類就是直接拷貝了父類的內容,然後結合自身的內容。而且存儲空間也是這個順序,即先父類分配空間,然後纔是子類空間。
3、靜態成員變量不佔用類空間,應該是確實沒有放入這個類的裏面,而且沒有指針指向它,只能通過類::來訪問,也就是說靜態成員是隨着類的存在而存在,而 不依賴於對象,它的存在意義主要還是區分,否則如何確定其意義,這還是體現了相關的都方一起的思想,比全局變量或者常量更方便使用和理解。
4、需要說明的是,虛函數對應的虛擬表在空間的其他位置,和對象是沒有聯繫的,但是虛擬表地址是和類統一的,也就是說一旦確定,無論在哪個對象中,其指針 值是一樣的,即虛擬表位置是一定的。指針放在對象的最前面,首先是指向虛函數的虛擬表指針,然後纔是其他成員變量空間。
5、
我認爲淺拷貝是一個不喜歡思考的懶漢,而深拷貝則是一個思維嚴謹,喜歡思考的人。對於懶漢來說,雖然給了他任務,但是他總是想盡量的少做一些事情,所以很多時候做出來的東西就是只看到了表面,不會去思考對不對。
struct X { int x; int y; };
對於懶漢來說,他很直白的看到了x,看到了y,然後就拷貝x和y,然後就不管了,反正我完成我的拷貝了,至於對不對,我不管。
而一旦有了引用或者指針,事情就不一樣了
struct X { int x; int y; int* p; };
int *p = new int(47); int *q = p;
如q與p都是指向一個物體一樣。
那麼如果原來的物體銷燬了,但是現在拷貝的物體還在,那麼這時候你拷貝後的物體的成員指針就是一個懸掛指針,指向了不再存在的物體,那麼你訪問的話,那就不知道會發生什麼了。
而對於深拷貝,這一個勤奮的人,他不會只做表面,他會把每一個細節都照顧好。於是,當他遇到指針的時候,他會知道new出來一塊新的內存,然後把原來指針指向的值拿過來,這樣纔是真正的完成了克隆體和原來的物體的完美分離,如果物體比作人的話,那麼原來的人的每一根毛細血管都被完美的拷貝了過來,而絕非只是表面。所以,這樣的代價會比淺拷貝耗費的精力更大,付出的努力更多,但是是值得的。當原來的物體銷燬後,克隆體也可以活的很好。
然而事實上是這個世界上大多都是懶漢,包括編程的人,編譯器等,所以默認的行爲都是淺拷貝,於是有時候你需要做一個勤奮的人,讓事情做正確,自己去完成深拷貝所需要的事情。
6、
7、
如果 const 位於 * 的左側,則 const 就是用來修飾指針所指向的變量,即指針指向爲常量;
如果 const 位於 * 的右側, const 就是修飾指針本身,即指針本身是常量。
8、
9、
浮點數判斷是否爲0
float : const EXPRESSION EXP = 0.000001
if ( a < EXP && a >-EXP)
10.
32位系統中,定義**a[3][4],則變量佔用內存空間爲 48bytes
**a[3][4]存儲的是指向地址的二維指針數組,32位系統一個地址4個字節,12*4=48byte
11.
在VC6.0中,stack的大小一般爲2M,不會自動增加。stack一般存放函數的參數列表、返回值、局部變量。
stack 不存儲全局變量的值的值
13、下列哪些http方法對於服務端和用戶端一定是安全的?
HEAD,GET,OPTIONS和TRACE視爲安全的方法,因爲它們只是從服務器獲得資源而不對服務器做任何修改,但是HEAD,GET,OPTIONS在用戶端不安全。而POST,PUT,DELETE和PATCH則影響服務器上的資源。
TRACE: 這個方法用於返回到達最後服務器的請求的報文,這個方法對服務器和客戶端都沒有什麼危險。OPTIONS:列出請求的資源所支持的所有方法。
14、下面函數的時間複雜度是
long foo(long x){
if(x<2) return 1;
return x*x*foo(x-1);
}
將這個遞歸轉換成循環的形式,其實就是一層的循環,所有時間複雜度爲O(N)
15、一棵非空的二叉樹的先序遍歷序列與後序遍歷序列正好相反,則該二叉樹一定滿足?
只有一個葉子結點
16、HTTPS是使用( )來保證信息安全的.
SSL
17、1.不建議在構造函數中拋出異常;
2.構造函數拋出異常時,析構函數將不會被執行,需要手動的去釋放內存
1.析構函數不應該拋出異常;
2.當析構函數中會有一些可能發生異常時,那麼就必須要把這種可能發生的異常完全封裝在析構函數內部,決不能讓它拋出函數之外;
3. 析構函數異常相對要複雜一些,存在一種衝突狀態,程序將直接崩潰:異常的被稱爲“棧展開(stack unwinding)”【備註】的過程中時,從析構函數拋出異常,C++運行時系統會處於無法決斷的境遇,因此C++語言擔保,當處於這一點時,會調用 terminate()來殺死進程。因此,當處理另一個異常的過程中時,不要從析構函數拋出異常, 拋出異常時,其子對象將被逆序析構
18、
對於滿足SQL92標準的SQL語句:
select foo,count(foo)from pokes where foo>10group by foo having count (*)>5 order by foo
其執行順序應該是?
FROM->WHERE->GROUP BY->HAVING->SELECT->ORDER BY
19、在網絡7層協議中,如果想使用UDP協議達到TCP協議的效果,可以在哪層做文章?
會話層
20、struct以最長的基本類型對齊。
21、開發C代碼時,經常見到如下類型的結構體定義:
typedef struct list_t{
struct list_t *next;
struct list_t *prev;
char data[0];
}list_t;
最後一行char data[0];的作用是?
A方便管理內存緩衝區
B減少內存碎片化
開發C代碼時,經常見到如下類型的結構體定義:
typedef struct list_t{
struct list_t *next;
struct list_t *prev;
char data[0];
}list_t;
最後一行char data[0];的作用是?