c++總結(一)

1, 若char是一字節,int是4字節,指針類型是4字節,代碼如下:

Class  CTest

{

Public:

CTest():m_chData(‘\0’),m_nData(0)

{

}

Virtual void mem_fun(){}

 

private:

   char m_chData;

   int m_nData;

   static char s_chData; //

};

Char CTest::s_chData=’\0’;

 

問:(1)若按1字節對齊sizeof(CTest)的值是多少? 9

    虛指針 (4)  +  char (1) + int(4) =9; 

   (2)若按4字節對齊sizeof(CTest)的值是多少? 12

  虛指針(4)+char(1+3)+int(4)=12;


static 的 作用

1)在函數體,一個被聲明爲staic的變量在這一函數被調用過程中維持其值不變。

2)在模塊內(但在函數體外),一個被聲明爲靜態的變量可以被模塊內所用函數訪問,但是不能被模塊外其它函數訪問。

它是一個本地的全局變量。

3)在模塊內,一個被聲明爲靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地範圍內使用。


引用和指針的區別?

1)引用必須被初始化,指針不必。

2)引用初始化以後不能被改變,指針可以改變所指的對象。

3)不存在指向空值的引用,但是存在指向空值的指針。

指針通過某個指針變量指向一個對象後,對它所指向的變量間接操作。程序中使用指針,程序可讀性差,

而引用本身就是目標變量的別名,對引用的操作就是對目標變量的操作。

流操作符<< 和 >>,賦值操作符=的返回值,拷貝構造函數的參數,賦值操作符=的參數,其它情況都推薦使用引用。


.h 頭文件中的 ifndef/define/endif 的作用?

防止該頭文件被重複引用。


#include和#include“file.h”的區別?

前者是從 Standard Library 的路徑尋找和引用file.h,而後者是從當前工作路徑搜尋並引用file.h

描述實時系統的基本特性

在特定的時間內完成特定的任務,實時性與可靠性。


全局變量和局部變量在內存中是否有區別?如果有,是什麼區別?

全局變量存儲在靜態數據區,局部變量在堆棧中。

什麼是平衡二叉樹

左右子樹都是平衡二叉樹 且 左右子樹 的 深度差值 的 絕對值 不大於 1.

堆棧溢出一般是由什麼原因導致的?

沒有回收垃圾資源

層次太深的遞歸調用


冒泡排序時間複雜度?

O(n^2)


什麼函數不能聲明爲虛函數?

constructor  構造函數


不能做switch()的參數類型?

SWITH(表達式),表達式可以是整型、字符型以及枚舉類型等表達式

switch()的參數類型不能是 實型

除了整型,枚舉類型,字符型,其他的都不行。譬如:字符串,浮點型這些都不可以作爲switch的參數類型。


##局部變量能否和全局變量重名?

能,局部會屏蔽全局。要用全局變量,需要使用 “::”

局部變量可以與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不是全局變量


##如何引用一個已經定義過的全局變量?

可以用引用頭文件的方式,也可以用extern關鍵字,如果用引用頭文件的方式來引用某個在頭文件中聲明的全局變量,假定你將那個變量寫錯了,那麼在

編譯期間會報錯,如果你用extern方式引用時,假定你犯了同樣的錯誤,那麼在編譯期間不會報錯,而在鏈接期間報錯。


##解釋堆和棧的區別


1)申請方式

stack 有系統自動分配。例如,聲明在函數中的一個局部變量 int b;系統自動在棧中爲b開闢空間

heap:需要程序員自己申請,並指明大小,在c中malloc 函數

p1=(char *)malloc(10);

p2=new char[10];

p1,p2 本身是在棧之中的。

2)申請後系統的響應

棧:只要棧的剩餘空間大於所申請空間,系統將爲程序提供內存,否則將報異常提示棧溢出。

堆:首先應該知道操作系統有一個記錄空閒內存地址的鏈表,當系統受到程序申請時,會遍歷該鏈表,尋找第一個空間大於所申請

空間的堆節點,然後將該節點從空閒界定鏈表中刪除,並將該節點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,

代碼中的delete 語句 才能正確的釋放本內存空間,另外,由於找到的堆節點的大小不一定正好等於申請的大小,系統會自動的將多餘的那一部分重新放入空閒鏈表之中。


3)申請大小的限制

棧:向低地址擴展的數據結構,是一塊連續的內存區域。這句話的意思是,棧頂的地址和棧的最大容量是系統預先規定好的,能從棧獲得的空間較小

堆:堆是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閒內存的、鏈表的遍歷方向是由低地址向高地址。

堆的大小受限於計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。

4)申請效率比較:

棧:有系統自動分配,速度快,但程序員無法控制。

堆:只有new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便。

5)堆和棧中的存儲內容

棧:在函數調用時,第一個進棧的是主函數中後一條指令的地址,然後是函數的各個參數,在大多數的C編譯器中,參數是由右往左入棧的,

然後是函數中的局部變量。注意靜態變量是不入棧的。

但本次函數調用結束後,局部變量先出棧,然後是參數,最後棧頂指針指向最開始存的地址,也就是主函數中的下一條指令,程序由改點繼續運行。

堆:一般是在堆的頭部用一個字節存放堆的大小,堆中的具體內容由程序員安排。


6)存續效率比較

char s1[]=“aaaaaaaaa”;

char *s2="bbbbbbbbbb";

aaaaaaaaa是在運行時刻賦值的

而bbbbbbbbbb是在編譯時就確定的。

但是,在以後的存取中,在棧上的數組比指針所指向的字符串(例如堆)快。

比如:

void main()

{

char a=1;

char c[]="1234567890";

char *p="1234567890";

a=c[1];

a=p[1];

return;

}

第一種在讀取時直接就把字符串中的元素讀到寄存器cl中,第二種則要先把指針值讀到edx中,在根據edx讀取字符,顯然慢了。。


##什麼是預編譯,何時需要預編譯?

預編譯又稱爲預處理,是做些代碼文本的替換工作。處理#開頭的指令,比如拷貝#include包含的文件代碼。#define 宏定義的替換,條件編譯等等,

就是爲編譯做的預備工作的階段,主要處理#開始的預編譯指令,預編譯指令指示了在程序正式編譯前就有編譯器進行的操作。

可以放在程序中的任何位置。

編譯系統在對程序進行通常編譯之前,先進行預處理,c提供的預處理功能主要有一下三種:

1)宏定義

2)文件包含

3)條件編譯


##關鍵字const含義?

const 意味着只讀,

int b = 500; 
const int* a = &              [1] 
int const *a = &              [2] 
int* const a = &              [3] 
const int* const a = &      [4] 

[1]和[2]的情況相同,都是指針所指向的內容爲常量(const放在變量聲明符的位置無關),這種情況下不允許對內容進行更改操作,如不能*a = 3 ;[3]爲指針本身是常量,而指針所指向的內容不是常量,這種情況下不能對指針本身進行更改操作,如a++是錯誤的;[4]爲指針本身和指向的內容均爲常量。




##volatile 有什麼含義,並給出三個不同的例子

一個定義爲volatile 的變量是說這個變量可能會被意想不到的改變,這樣,編譯器就不會去假設這個變量的值了。

精確的說,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器裏的備份,

下面是volatile變量的幾個例子

1)並行設備的硬件寄存器

2)一箇中斷服務子程序中會訪問道德非自動變量

3)多線程應用中被幾個任務共享的變量。


一個參數既可以是const還可以是volatile嗎?解釋爲什麼?

是的 一個例子是 只讀的狀態寄存器。它是volatile因爲它可能被意想不到的改變,它是const因爲程序不應該試圖去修改它


一個指針可以是volatile嗎?爲什麼?

是的,儘管不常見,一個例子是當一箇中斷服務子程序修改一個指向一個buffer的指針時。


3)下面的函數有什麼錯誤:

int square(volatile int *ptr)

{

return *ptr **ptr;

}


因爲 ptr 是 volatile

編譯器會產生 下面的代碼:

int square(volatile int *ptr)

{

  int a,b;

  a=*ptr;

  b=*ptr;

  return a*b;

}


由於 *ptr的值可能被意想不到的改變,因此a和 b 可能是不同的。結果,這段代碼可能返回不是你期望的平方值!


long square(volatile int *ptr)

{

  int a;

  a=*ptr;

  return a*a;

}



##三種基本的數據模型

層次模型   網狀模型  關係模型


##結構和聯合有何區別

呵呵


##描述內存分配凡是以及他們的區別?

1)靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如,全局變量,static變量

2)棧上創建

3)在堆上分配。//使用靈活,問題多


##const與#define相比,有何優點?

1)const常量有數據類型,而宏常量沒有數據類型,編譯器可以對前者進行類型安全檢查。對後者只進行字符替換,沒有類型安全檢查,字符替換可能產生意想不到的錯誤

2)有些調試工具可以對const常量進行調試,但是不能對宏常量進行調試。


##數組和指針的區別

當數組作爲函數的參數進行傳遞時,該數組自動退化爲同類型的指針

char a[]="hello world";

char *p=a;

cout<<sizeof(a)<<endl;//12

cout<<sizeof(p)<<endl;//4

計算數組和指針的內存容量

void Func(char a[100])

{

cout<<sizeof(a)<<endl;//4而不是100

}



##分別寫出BOOL,int,float ,指針類型 變量 a 與 “零”的比較語句

BOOL  if(!a) or if(a)

int if(a==0)

float const EXPRESSION EXP=0.000001 //typedef float EXPRESSION;

if(a<EXP&&a>EXP)

pointer: if(a!=NULL) or if(a==NULL)


##如何判斷一段程序是由C編譯程序還是有C++編譯程序編譯的?

#ifdef __cplusplus

cout<<"c++";

#else

cout<<"c";

#endif   


##論述含參數的宏與函數的優缺點 

              帶參宏  函數

處理時間 編譯時 程序運行時

類型參數 沒有參數類型問題 定義實參,形參類型

處理過程 不分配內存 分配內存

程序長度 變長 不變

運行速度 不佔運行時間 調用和返回佔用時間


##用兩個棧實現一個隊列功能?

思路:

  假設兩個棧 A 和B,且都爲空。
  可以認爲棧 A 爲提供入隊列的功能,棧 B 提供出隊列的功能。
  入隊列: 入棧 A 
  出隊列:
  1 如果棧B 不爲空,直接彈出棧 B 的數據。
  2 如果棧 B 爲空,則依次彈出棧 A 的數據,放入棧 B 中,再彈出棧 B 的數據。



##A.c和B.c 兩個文件中使用了兩個相同名字的static變量,編譯的時候會不會有問題?

這兩個static 變量會保存到哪裏?


static 的全局變量,表明這個變量僅在本模塊中有意義,不會影響其他模塊。

他們都放在數據區,但是編譯器對他們的命名是不同的。

如果要使其他模塊也有意義的話,需要使用extern關鍵字。


##一個單向鏈表,不知道頭結點,一個指針指向其中的一個節點,問如何刪除這個指針所指的節點?


將這個指針指向的next節點值copy到本節點,將next指向next->next,並隨後刪除原next指向的節點。


##閱讀代碼 找錯

void foo(void)

{

unsigned int a=6;

int b=-20;

(a+b>6)?puts(">6"):puts("<=6");

}


當表達式中存在有符號類型和無符號類型時所有的操作數都自動轉換爲無符號類型。因此,-20變成了一個非常大的正整數

所以該表達式的計算結果大於6.


##

unsigned int zero=0;

unsigned int compzero=0xFFFF; //wrong should be     unsigned int compzero=~0;


##a+++b     //a++  +b





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章