C++語言常見知識點
C++基礎
變量存在的意義是什么?
作用:給一段指定的內(nèi)存空間起名,方便我們管理操作這塊內(nèi)存。
int a=10;
常量的兩種定義方式
1、#define PI 3.14 2、const int a=10;
用于記錄程序中不可更改的數(shù)據(jù)。
標識符的命名規(guī)則
1、不能是關鍵字
2、只能由字母、下劃線、數(shù)字構(gòu)成
3、不能數(shù)字開頭
4、區(qū)分大小寫
為什么要有數(shù)據(jù)類型?
C++規(guī)定在一個變量或者常量時,必須要指出相應的數(shù)據(jù)類型,否則無法給變量分配內(nèi)存。
存在的意義:給變量分配合適的內(nèi)存空間,不要造成浪費。
sizeof關鍵字有什么用?
利用sizeof關鍵字可以統(tǒng)計數(shù)據(jù)類型所占用內(nèi)存大小(字節(jié)大小)。
sizeof( 數(shù)據(jù)類型/變量 )
科學計數(shù)法表示
float f=3e2;// 3* (10^2)
float f2=3e-2;// 3* (0.1^2)
C++中的字符變量
char a='a';
- C/C++中字符型變量只占用1個字節(jié)。
- 字符型變量并不是把字符本身放到內(nèi)存中存儲,而是將對應的ASCII碼放入到存儲單元。
- cout<<(int)a<<endl; a=>97;A=>65
轉(zhuǎn)義字符:用于表示一些不能顯示出來的ASCII字符。 \n \\ \t
C++生成隨機數(shù)
int num = rand() % 100; // 0~99
goto語句
不推薦用,知道就好。
cout << "a" << endl;
cout << "b" << endl;
goto FLAG;
cout << "c" << endl;
FLAG:
cout << "d" << endl;
/*
a
b
d
*/
數(shù)組
所謂數(shù)組,就是一個集合,里面存放了相同類型的數(shù)據(jù)元素。
特點:1、每個數(shù)據(jù)元素都是相同的數(shù)據(jù)類型2、數(shù)組由連續(xù)的內(nèi)存地址組成
一維數(shù)組名的用途
int arr[5]={1,2,3,4,5};
1、可以統(tǒng)計整個數(shù)組在內(nèi)存中的長度
sizeof(arr)、sizeof(arr[0])
2、獲取數(shù)組在內(nèi)存中的首地址。
cout<<arr<<endl;
cout<<&arr[0]<<endl; // 獲取數(shù)組中第一個元素地址。與數(shù)組首地址一樣
二維數(shù)組名的用途
int arr[2] [3]={{1,2,3},{4,5,6}};
1、可以統(tǒng)計整個數(shù)組在內(nèi)存中的長度
sizeof(arr)、sizeof(arr[0]) 第一行所占用的內(nèi)存空間大小、sizeof(arr[0] [0]) 第一個元素所占內(nèi)存空間大小
sizeof(arr)/sizeof(arr[0]) 獲取行數(shù)、sizeof(arr[0])/sizeof(arr[0] [0]) 獲取列數(shù)
2、獲取數(shù)組在內(nèi)存中的首地址。
cout<<arr<<endl;
cout<<arr[0]<<endl; 獲取第一行數(shù)據(jù)首地址
cout<<arr[1]<<endl;
函數(shù)有什么用?
作用:將一段經(jīng)常使用的代碼封裝起來,減少重復代碼。
一個較大的程序,一般分為若干個程序塊,每個模塊實現(xiàn)特定的功能。
什么是函數(shù)值傳遞?
所謂值傳遞,就是函數(shù)調(diào)用時實參將數(shù)傳入給形參。
值傳遞時,如果形參發(fā)生改變,并不影響實參。
void swap(int a, int b)
{
cout << "2:a= " << a << endl;
cout << "2:b= " << b << endl;
int temp = a;
a = b;
b = temp;
cout << "2:a= " << a << endl;
cout << "2:b= " << b << endl;
}
int main()
{
int a = 10;
int b = 20;
cout << "1:a= " << a << endl;
cout << "1:b= " << b << endl;
swap(a, b);
cout << "1:a= " << a << endl;
cout << "1:b= " << b << endl;
system("pause");
return 0;
}
/*
1:a= 10
1:b= 20
2:a= 10
2:b= 20
2:a= 20
2:b= 10
1:a= 10
1:b= 20
*/
指針有什么用?
作用:可以通過指針間接訪問內(nèi)存。
- 內(nèi)存編號是從0開始記錄的,一般用十六進制數(shù)字表示
- 可以利用指針變量來保存地址
int a = 10;
int* p = &a;// 讓指針p記錄a的地址
cout << "a= " << a << endl;
cout << "*p= " << *p << endl;// 解引用
cout << "&a= " << &a << endl;// &取地址
cout << "p= " << p << endl;
/*
a= 10
*p= 10
&a= 000000A2FEEFF5C4
p= 000000A2FEEFF5C4
*/
指針這種數(shù)據(jù)類型所占用的內(nèi)存空間有多大呢?
sizeof(int *)
? 32位操作系統(tǒng),占用4個字節(jié)
? 64位操作系統(tǒng),占用8個字節(jié)
什么是空指針?有什么用?什么是野指針?
空指針:指針變量指向內(nèi)存中編號為0的空間。
? 用途:初始化指針變量 int * p=NULL;
? 注意:空指針指向的內(nèi)存不可以訪問(0~255之間的內(nèi)存編號是系統(tǒng)占用的,因此不可訪問)
野指針:指針變量指向非法的內(nèi)存空間。程序中,避免出現(xiàn)野指針。
const修飾指針有哪些情況?有什么區(qū)別?
1、const修飾指針 --- 常量指針
const int * p=&a; 指針指向可以修改,但指針指向的值不可以改。*p=20(X)p=&b(V)
2、const修飾常量 --- 指針常量
int * const p=&a; 指針指向不可以修改,但指針指向的值可以改。*p=20(V)p=&b(X)
【記法:const 和 * 誰在前,對應的就不能變。例如const在前,常量值就不能變;*在前,指針的指向不能變】
3、const既修飾指針又修飾常量
const int * const p=&a; 指針指向不可以修改,但指針指向的值不可以改。*p=20(X)p=&b(X)
int m = 10;
int n = 10;
const int* pt1 = &m;// 常量指針
pt1 = &n;
//*pt1 = 20;// 報錯
int* const pt2 = &m;// 指針常量
//pt2 = &n;// 報錯
*pt2 = 20;
const int* const pt3 = &m;// const既修飾指針又修飾常量
//pt3 = &n;// 報錯
//*pt3 = 20;// 報錯
如何利用指針訪問數(shù)組中的元素?
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
cout << arr[0] << endl;
int* ptr = arr;// arr就是arr數(shù)組的首地址
cout << ptr << endl;
ptr++;// ptr向后偏移4個字節(jié)
cout << ptr << endl;
int* ptr2 = arr;
for (int i = 0; i < 10; i++)
{
cout << *ptr2 << " ";
ptr2++;
}
指針作為函數(shù)參數(shù)會發(fā)生什么情況?
可以修改實參的值。
// 值傳遞
void swap(int a, int b)
{
int temp = b;
b = a;
a = temp;
cout << "內(nèi)部a= " << a << endl;
cout << "內(nèi)部b= " << b << endl;
}
// 引用傳遞
void swap2(int* a, int* b)
{
int temp = *b;
*b = *a;
*a = temp;
cout << "內(nèi)部a= " << *a << endl;
cout << "內(nèi)部b= " << *b << endl;
}
int a = 10;
int b = 20;
//swap(a, b); 10 20
swap2(&a, &b);20 10
cout << "a= " << a << endl;
cout << "b= " << b << endl;
示例:指針結(jié)合數(shù)組和函數(shù)
// 數(shù)組的冒泡排序
void bubbleSort(int* arr, int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
}
// 打印數(shù)組
void printArray(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << " ";
}
}
int main()
{
int arr[] = { 3,1,7,4,6,9,10,2,5,8 };
int len = sizeof(arr) / sizeof(arr[0]);// 數(shù)組長度
cout << "排序前:";
printArray(arr, len);// 打印數(shù)組
cout << endl;
bubbleSort(arr, len);// 給數(shù)組排序
cout << "排序后:";
printArray(arr, len);// 打印數(shù)組
cout << endl;
system("pause");
return 0;
}
什么是結(jié)構(gòu)體?
結(jié)構(gòu)體屬于用戶自定義的數(shù)據(jù)類型,允許用戶存儲不同的數(shù)據(jù)類型。
struct Student
{
string name;
int age;
float score;
};
struct Teacher
{
int id;
string name;
int age;
struct Student stu;// 結(jié)構(gòu)體嵌套
};
// 結(jié)構(gòu)體作值傳遞
void PrintStudent(struct Student s)
{
s.age = 100;
cout << s.name << " " << s.age << " " << s.score << endl;
}
// 結(jié)構(gòu)體作引用傳遞:可以減少空間,不會復制新的副本出來
void PrintStudent2(struct Student* s)
{
s->age = 200;
cout << s->name << " " << s->age << " " << s->score << endl;
}
// 結(jié)構(gòu)體作引用傳遞:可以減少空間,不會復制新的副本出來。
// 防止誤操作,加const,只能讀不能寫
void PrintStudent2(const struct Student* s)
{
cout << s->name << " " << s->age << " " << s->score << endl;
}
int main()
{
struct Student s1;
s1.name="張三";
s1.age=21;
s1.score=100;
Student s2={"李四",20,80};
cout<<s1.name<<" "<<s1.age<<" "<<s1.score<<endl;
cout<<s2.name<<" "<<s2.age<<" "<<s2.score<<endl;
// 結(jié)構(gòu)體數(shù)組
Student stus[2] = { s1,s2 };
stus[0].name="張飛";
// 結(jié)構(gòu)體指針
Student * p=&s1;
cout<< p->name << " " << p->age << " " << p->score;
// 嵌套結(jié)構(gòu)體
Teacher t;
t.id=1;
t.name="老王";
t.age=40;
t.stu=s1;
// 結(jié)構(gòu)體作函數(shù)參數(shù)
cout << "------------------" << endl;
PrintStudent(s2);
cout << s2.name << " " << s2.age << " " << s2.score << endl;
PrintStudent2(&s2);
cout << s2.name << " " << s2.age << " " << s2.score << endl;
system("pause");
return 0;
}
C++核心
C++的內(nèi)存分區(qū)有哪些?為什么要分區(qū)?
程序運行前:
1、代碼區(qū)(存放函數(shù)體的二進制代碼【共享、只讀】,由操作系統(tǒng)進行管理)
2、全局區(qū)(存放全局變量和靜態(tài)變量以及常量【字符串常量和const修飾的全局常量】,程序結(jié)束時由操作系統(tǒng)釋放)
程序運行后:
3、棧區(qū)(由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量等)
4、堆區(qū)(由程序員分配和釋放,若程序員不釋放,程序結(jié)束時由操作系統(tǒng)回收。主要利用new在堆區(qū)開辟內(nèi)存;delete釋放)
int * p = new int(10);//*p 存放在棧區(qū),new int(10)存放在堆區(qū)
cout<< *P <<endl;//10
delete p;
// new、delete開辟數(shù)組
int * arr= new int[10];
for(int i=0;i<10;i++)
{
arr[i]=i+100;
}
for(int i=0;i<10;i++)
{
cout<<arr[i]<<endl;//100~109
}
delete []arr;
分區(qū)存在的意義:不同區(qū)域存放的數(shù)據(jù),賦予不同的生命周期,給我們更大的靈活編程。
C++中的引用有什么用?
給變量起別名。 數(shù)據(jù)類型 & 別名 = 原名
注意:1、引用必須初始化 2、一旦初始化之后,就不可以更改了。
使用引用作函數(shù)參數(shù)的優(yōu)點是什么?
函數(shù)傳參時,可以利用引用的技術讓形參修飾實參。可以簡化指針修改實參。
void swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int m = 10;
int n = 20;
cout << m << endl;//10
cout << n << endl;//20
swap(m, n);
cout << m << endl;//20
cout << n << endl;//10
system("pause");
return 0;
}
引用的本質(zhì)是什么?
引用的本質(zhì)在c++內(nèi)部實現(xiàn)是一個指針常量(指針的指向不能改變,值可以改變)。
為什么會有常量引用?
常量引用主要用來修飾形參,防止誤操作。 const int& a=10; //(X)a=20;
封裝有什么意義?
1、將屬性和行為作為一個整體,變現(xiàn)生活中的事物。
2、將屬性和行為加以權(quán)限控制。A. public公共權(quán)限 B. protected 保護權(quán)限(子可以訪問父) C. private 私有權(quán)限
結(jié)構(gòu)體和類的區(qū)別是什么?
c++中,struct和class唯一的區(qū)別就在于 默認的訪問權(quán)限不同。struct 公共;class private
成員屬性設置成私有的好處是什么?
1、可以控制自己讀寫權(quán)限( get,set方法) 2、對于 寫,可以檢測數(shù)據(jù)的有效性 (set方法內(nèi)條件判斷)
構(gòu)造函數(shù)和析構(gòu)函數(shù)的作用是什么?
構(gòu)造函數(shù):對象的初始化,無需手動調(diào)用,只會調(diào)用一次
析構(gòu)函數(shù):在對象銷毀前系統(tǒng)自動調(diào)用,執(zhí)行一些清理工作,只會調(diào)用一次【在堆區(qū)開辟的數(shù)據(jù)釋放掉】
構(gòu)造函數(shù)的調(diào)用規(guī)則
-
如果用戶定義有參構(gòu)造函數(shù),c++不在提供默認無參構(gòu)造,但是會提供默認拷貝構(gòu)造
-
如果用戶定義拷貝構(gòu)造函數(shù),c++不會再提供其他構(gòu)造函數(shù)
深拷貝和淺拷貝是什么?有什么區(qū)別?
淺拷貝:簡單的賦值拷貝操作
深拷貝:在堆區(qū)重新申請空間,進行拷貝操作
區(qū)別:
淺拷貝的問題:

深拷貝解決:

B類中有對象A作為成員,A為對象成員。那么創(chuàng)建B對象時,A與B的構(gòu)造和析構(gòu)的順序是誰先誰后?
A的構(gòu)造——>B的構(gòu)造——>B的析構(gòu)——>A的析構(gòu)
C++靜態(tài)成員的注意事項
包括:
靜態(tài)成員變量:1、所有對象共享同一份數(shù)據(jù) 2、在編譯階段分配內(nèi)存(全局區(qū))
3、類內(nèi)聲明,類外初始化 (注意訪問權(quán)限)int Person::m_A=100; 訪問:p.m_A; p1.m_A; Person::m_A;
靜態(tài)成員函數(shù):(注意訪問權(quán)限)1、所有對象共享同一個函數(shù) 2、靜態(tài)成員函數(shù)只能訪問靜態(tài)成員變量
static void func(){} 訪問:p.func(); Person::func();
C++的成員變量和成員函數(shù)分開存儲。
只有非靜態(tài)成員變量屬于類對象上。sizeof(p)
? 如果類什么都沒有,空對象占1個字節(jié);有非靜態(tài)成員變量,按照對應變量的大小算
每一個非靜態(tài)成員函數(shù)只會誕生一份函數(shù)實例,也就是說多個同類型的對象會共用同一份代碼。
this指針有什么用?
this指針指向被調(diào)用的成員函數(shù)所屬的對象。本質(zhì)是指針常量
- 形參和變量成員同名時,可用this指針來區(qū)分
- 在類的非static成員函數(shù)中返回對象本身,可使用return *this;
const修飾成員函數(shù)的用途是什么?
常函數(shù):1、常函數(shù)內(nèi)不能修改成員屬性 2、成員屬性聲明時加關鍵字mutable后,在常函數(shù)中依然可以修改。
void showPerson() const { }
常對象:常對象只能調(diào)用常函數(shù)
友元的目的是什么?
讓一個函數(shù)或者類 能夠訪問另一個類中的私有成員。friend
什么是運算符重載?
對已有的運算符重新進行定義,賦予其另一種功能,以適應不同的數(shù)據(jù)類型。

使用繼承有什么好處?
減少重復代碼 class Java: public BasePage { }
繼承方式:1、公共繼承 2、保護繼承 3、私有繼承

父類中所有非靜態(tài)成員屬性都會被子類繼承下去。sizeof(son) 包括父類的私有非靜態(tài)屬性
繼承中父類和子類的構(gòu)造和析構(gòu)順序誰先誰后?
Base構(gòu)造——>Son構(gòu)造——>Son析構(gòu)——>Base析構(gòu)
當子類和父類出現(xiàn)同名的成員,如何通過子類對象,訪問到子類或父類中同名的數(shù)據(jù)呢?
-
訪問子類同名成員,直接訪問即可。 s.m_A; s.Func();
-
訪問父類同名成員,需要加作用域。 s.Base::m_A; s.Base::Func();
靜態(tài)成員同名情況下的處理方式一致。
菱形繼承問題

使用 虛繼承 解決菱形繼承的問題。


哪些屬于多態(tài)?
1、靜態(tài)多態(tài):函數(shù)重載 和 運算符重載屬于靜態(tài)多態(tài),復用函數(shù)名。 編譯階段確定函數(shù)地址
2、動態(tài)多態(tài):派生類和虛函數(shù)實現(xiàn)運行時多態(tài)。 運行階段確定函數(shù)地址
#include <iostream>
using namespace std;
class Base
{
public:
virtual void speak()
{
cout << "Base" << endl;
}
};
class Son1 :public Base
{
public:
//重寫B(tài)ase方法
void speak()
{
cout << "Son1" << endl;
}
};
class Son2 :public Base
{
public:
//重寫B(tài)ase方法
void speak()
{
cout << "Son2" << endl;
}
};
void Speak(Base& base)//Base& base=son1
{
base.speak();
}
int main()
{
Son1 son1;
Speak(son1);//Son1
Son2 son2;
Speak(son2);//Son2
system("pause");
return 0;
}

多態(tài)的優(yōu)點有哪些?
1、代碼組織結(jié)構(gòu)清晰 2、可讀性強 3、利于前期和后期的擴展和維護
純虛函數(shù)的由來?什么是抽象類,有什么特點?
在多態(tài)中,通常父類中的虛函數(shù)的實現(xiàn)是毫無意義的,主要都是調(diào)用子類重寫的內(nèi)容。
可將虛函數(shù)改成 純虛函數(shù)。【virtual 返回值類型 speak() = 0;】
當類中有了純虛函數(shù),這個類也稱為抽象類。
- 無法實例化對象
- 子類必須重寫抽象類中的純虛函數(shù),否則也屬于抽象類。
虛析構(gòu)和純虛析構(gòu)的用處?
多態(tài)使用時,如果子類中有屬性開辟到堆區(qū),那么父類指針在釋放時無法調(diào)用到子類的析構(gòu)代碼。
——使用虛析構(gòu)或者純虛析構(gòu)
virtual ~Base() { } | virtual ~Base() = 0;Base::~Base() { }
共性:1、可以解決父類指針釋放子類對象 2、都需要具體的函數(shù)實現(xiàn)
區(qū)別:如果是純虛析構(gòu),該類屬于抽象類,無法實例化對象。
文件操作
頭文件:
ofstream:寫操作 ifstream:讀操作 fstream:讀寫操作

浙公網(wǎng)安備 33010602011771號