這篇博客是對於我個人的知識的複習,當然如果有某位大佬能夠指出這裏面有哪些概念含糊不清或者難懂,麻煩指出來感激不盡。
1.const
const:用const修飾的變量是“可讀的”,即可以被訪問,但是無法修改。
const可以修飾指針,數據成員,成員函數,類對象
修飾指針
指針常量和常量指針
顧名思義,類似
int* const p;//指針常量,const修飾p
const int* q;//常量指針
int const *r;//常量指針
- 指針常量是一個常量,不能修改該常量的值,但是可以改變該常量指向內存的儲存的值。
- 常量指針是一個指針,可以改變該指針的值,但是無法改變常量指向內存的儲存的值。
- 可以通過const與*的位置進行判斷類型。
修飾數據成員
修飾數據成員後,數據成員變成“只讀”形式,不能被修改,只能被初始化在初始化列表中,不能被修改。
class Const_test{
public:
Const_test(int v):value(v){
}
private:
const int value;
};
修飾成員函數
const修飾的成員函數,能夠訪問const成員變量和非const變量,但是隻能調用const修飾的成員函數。
class Const_test{
public:
Const_test(int v):value(v){
}
void display()const{
age = 10; //錯誤
int temp = 10; //正確
temp = age;
print();//錯誤
}
void dispaly(){//重載
}
void print(){
}
private:
int age;
const int value;
};
修飾類對象
const修飾函數,是從函數層面,不修改數據。const修飾對象,是從對象的層面,不修改數據。只能調用const成員函數。
面試題const和define宏的區別?
const修飾的變量,會分配內存的變量,而宏在預處理過程中進行的字符串替換
const修飾的變量,在編譯上會有安全檢查,本質上仍然可以修改,只是編譯器讓其無法修改,可以用指針的方式來繞過編譯器,對const變量進行修改。
define是將字符進行替換,很容易造成隱祕的錯誤。
2.static
- 聲明static的函數無法被其他的源程序所引用
- 聲明static的成員對象,不屬於單個對象,而屬於這個類,保存在靜態區中,在類外進行初始化
- 聲明static的成員函數,只能訪問static變量和static函數,和聲明static的成員對象類似,不屬於單個對象,而屬於這個類,調用使用類名::函數名
3.sizeof
sizeof是關鍵詞而不是函數,用來計算變量大小
面試題說出sizeof和strlen的區別
- sizeof是關鍵詞,strlen是函數
- strlen傳入參數爲字符串,且必須以\0結尾,計數器遇到\0會退出
- sizeof計算的是傳入的操作數的字節大小,傳入的操作數可以是int char 或者函數,例如int g() sizeof(g()) == sizeof(int)
- sizeof在大部分的編譯器中都是編譯時,運算,strlen函數則時在程序運行時進行運算。
- sizeof計算結構體遵循內存對齊,且只計算棧上的成員,對於靜態變量不會進行運算,無論有多少個虛函數,只計算一個虛函數指針的大小。
- sizeof計算繼承父類的子類的對象大小,因存在繼承關係,所以派生類的sizeof結果需要加上基類的sizeof結果,如果子類和父類都有虛函數,只計算一次虛函數的指針大小。
#include<iostream>
using namespace std;
struct A1 {
int a;
char c;
static char c1; //BSS段,不屬於棧區
A1();
~A1() {}
virtual void f1() {}
virtual void f2() {}
virtual void f3() {}
};
struct A2 : public A1{
float f;
void f1(){}
void f2(){}
void f3(){}
virtual void g1(){}
virtual void g2(){}
};
int main(int argc, char* argv[]) {
cout << sizeof(A1) << endl; //12
cout << sizeof(A2) << endl; //16
getchar();
return 0;
}
面試題寫一個三數求最大的宏函數
#define MAX(a,b,c) (((a)>(b))?((a)>(c)?(a):(c)):((b)>(c)?(b):(c)))