C++的編程精華,走過路過千萬不要錯過??!廢話少說,我們直接進入正題!?。?!
函數(shù)高級
C++的函數(shù)提高
函數(shù)默認參數(shù)
在C++中,函數(shù)的形參列表中的形參是可以有默認值的。
語法:返回值類型 函數(shù)名 (參數(shù) = 默認值){}
示例:
#include<iostream>
using namespace std;
?
//函數(shù)的默認參數(shù)
//如果我們自己傳入數(shù)據(jù),就用自己的數(shù)據(jù),如果沒有那就用默認值
//語法:返回值類型 函數(shù)名稱(形參 = 默認值){}
int func(int a,int b = 20,int c = 30)
{
? ?return a + b + c;
}
?
//注意事項
//如果某個位置已經(jīng)有了默認參數(shù),那么這個位置從左往右都必須有默認值
//如果函數(shù)聲明有了默認參數(shù),函數(shù)實現(xiàn)就不能有默認值
//聲明和實現(xiàn)只能有一個默認參數(shù)
int func2(int a = 10,int b = 20);
int func2(int a = 10,int b = 20)//error
{
? ?return a + b;
}
?
?
int main()
{
? ?cout << func(10) << endl;
? ?cout << func(30) << endl;
? ?return 0;
}
函數(shù)占位參數(shù)
C++中函數(shù)的形參列表里可以有占位參教,用來做占位,調用函數(shù)時必須填補該位置
語法:返回值類型 函數(shù)名 (數(shù)據(jù)類型){}
在現(xiàn)階段函數(shù)的占位參數(shù)存在意義不大,但是后面的課程中會用到該技術
示例文章來源:http://www.zghlxwxcb.cn/news/detail-416715.html
#include<iostream>
using namespace std;
//函數(shù)占位參數(shù),占位參數(shù)也可以有默認參數(shù)
void func(int a,int )
{
? ?cout << "this is func" << endl;
}
?
int main()
{
? ?func(10,10);//占位參數(shù)必須填補
? ?return 0;
}
函數(shù)重載
作用:函數(shù)名可以相同,提高復用性
函數(shù)重載滿足條件:
-
同一個作用域下
-
函數(shù)名稱相同
-
函數(shù)參數(shù)類型不同或者個數(shù)不同或者順序不同
注意:函數(shù)的返回值不可以作為函數(shù)重載的條件
示例
#include<iostream>
using namespace std;
?
//函數(shù)重載
//可以讓函數(shù)名相同,提高復用性
?
//函數(shù)重載滿足條件
//1. 同一個作用域下
//2. 函數(shù)名稱相同
//3. 函數(shù)參數(shù)類型不同或者個數(shù)不同或者順序不同
void func()
{
? ?cout << "func函數(shù)的調用" << endl;
}
?
void func(int a)
{
? ?cout << "func(int a)函數(shù)的調用!" << endl;
}
?
void func(double a)
{
? ?cout << "func(double a)函數(shù)的調用!" << endl;
}
?
void func(int a, double b)
{
? ?cout << "func(int a, double b)函數(shù)的調用!" << endl;
}
?
void func(double a,int b)
{
? ?cout << "func(double a,int b)函數(shù)的調用!" << endl;
}
?
int main()
{
? ?func();
? ?func(1);
? ?func(3.14);
? ?func(1,3.14);
? ?func(3.14,1);
? ?return 0;
}
func函數(shù)的調用
func(int a)函數(shù)的調用!
func(double a)函數(shù)的調用!
func(int a, double b)函數(shù)的調用!
func(double a,int b)函數(shù)的調用!
注意
int func(double a,int b)//這個無法重載,函數(shù)重載不可以作為函數(shù)重載條件
{
? ?cout << "func(double a,int b)函數(shù)的調用!" << endl;
}
函數(shù)重載的注意事項
-
引用作為重載條件
-
函數(shù)重載碰到函數(shù)默認參數(shù)
示例
#include<iostream>
using namespace std;
//引用作為重載條件
void func(int &a)
{
? ?cout << "func(int &a)" << endl;
}
?
void func(const int &a)//const int &a = 10;這是合法的代碼
{
? ?cout << "func(const int &a)" << endl;
}
//函數(shù)重載碰到默認參數(shù)
void func2(int a,int b = 10)
{
? ?cout << "func2(int a,int b)" << endl;
}
?
void func2(int a)
{
? ?cout << "func2(int a)" << endl;
}
?
int main()
{
? ?int a = 10;
? ?func(a);//實現(xiàn)的是func(int &a)的函數(shù)
? ?func(10);//實現(xiàn)的是fun(const int &a)的函數(shù)
? ?func2(10);//當函數(shù)重載碰到默認參數(shù),就會出現(xiàn)二義性,error
? ?return 0;
}
內存模型
C++核心編程
主要針對C++面向對象編程技術做詳細講解,探討C++中的核心和精髓。
內存分區(qū)模型
C++程序在執(zhí)行時。將內存大方向劃分為4個區(qū)域
-
代碼區(qū):存放函數(shù)體的二進制代碼。由操作系統(tǒng)進行管理的。
-
全局區(qū):存放全局變量和靜態(tài)變量以及常量。
-
棧區(qū):由編譯器自動分配釋放,存放函數(shù)的參數(shù)值局部變量等。
-
堆區(qū):由程序員分配和釋放,若程序員下釋放,程序結束時由操作系統(tǒng)回收。
內存四區(qū)意義:
不同區(qū)域存放的數(shù)據(jù)。暖予不同的生金周明,給我們更大的靈活編程
程序運行前
在程序編譯后,生成了exe可執(zhí)行程序,未執(zhí)行該程序前分為兩個區(qū)域 代碼區(qū):
-
存放CPU執(zhí)行的機器指令
-
代碼區(qū)是共享的,共享的目的是對于頻繁被執(zhí)行的程序,只需要在內存中有一份代碼即可
-
代碼區(qū)是只讀的,使其只讀的原因是防止程序意外地修改了它的指令
全局區(qū):
-
全局變量和靜態(tài)變量存放在此
-
全局區(qū)還包含了常量區(qū),字符串常量和其他常量也存放在此
-
該區(qū)域的數(shù)據(jù)在程序結束后由操作系統(tǒng)釋放
示例:
#include<iostream>
using namespace std;
//全局變量
int g_a = 10;
int g_b = 10;
//const修飾的全局變量
const int c_g_a = 10;
const int c_g_b = 10;
int main()
{
? ?//創(chuàng)建普通的局部變量
? ?int a = 10;
? ?int b = 10;
? ?cout << "局部變量a的地址為:" << (int*)&a << endl;
? ?cout << "局部變量b的地址為:" << (int*)&b << endl;
? ?
? ?cout << "全局變量g_a的地址為:" << (int*)&g_a << endl;
? ?cout << "全局變量g_b的地址為:" << (int*)&g_b << endl;
? ?
? ?//靜態(tài)變量,在普通變量前面加static,屬于靜態(tài)變量
? ?static int s_a = 10;
? ?static int s_b = 10;
? ?cout << "靜態(tài)變量s_a的地址為:" << (int*)&s_a <<endl;
? ?cout << "靜態(tài)變量s_b的地址為:" << (int*)&s_b <<endl;
? ?
? ?//常量
? ?//字符串常量
? ?cout << "字符串常量的地址:" << (int*)&"hello" << endl;
? ?//const修飾常量
? ?cout << "全局常量 c_g_a的地址為:" << (int*)&c_g_a << endl;
? ?cout << "全局常量 c_g_b的地址為:" << (int*)&c_g_b << endl;
? ?//const修飾的局部變量
? ?const int c_l_a = 10;
? ?const int c_l_b = 10;
? ?cout << "局部變量 c_l_a的地址為:" << (int*)&c_l_a << endl;
? ?cout << "局部變量 c_l_b的地址為:" << (int*)&c_l_b << endl;
? ?return 0;
}
局部變量a的地址為:0x61fe1c
局部變量b的地址為:0x61fe18
全局變量g_a的地址為:0x403010
全局變量g_b的地址為:0x403014
靜態(tài)變量s_a的地址為:0x403018
靜態(tài)變量s_b的地址為:0x40301c
字符串常量的地址:0x40409f
全局常量 c_g_a的地址為:0x404004
全局常量 c_g_b的地址為:0x404008
局部變量 c_l_a的地址為:0x61fe14
局部變量 c_l_b的地址為:0x61fe10
總結:
-
C++中在程序運行前分為全局區(qū)和代碼區(qū)
-
代碼區(qū)特點是共享和只讀
-
全局區(qū)中存放全局變量、靜志變量、常量
-
常量區(qū)中存放const修飾的全局常量和字符串常量
程序運行后
棧區(qū):
-
由編譯器自動分配程放存放函數(shù)的參數(shù),局部變量等
-
注意事項:不要返回局部變量的地址,棧區(qū)開辟的數(shù)據(jù)由編譯器自動釋放
示例:
#include<iostream>
using namespace std;
//棧區(qū)數(shù)據(jù)注意事項,不要返回局部變量的地址
//棧區(qū)的數(shù)據(jù)由編譯器管理開辟和釋放
int* func(int b)//形參數(shù)據(jù)也會放在棧區(qū)
{
? ?b = 100;
? ?int a = 10;//局部變量 存放在棧區(qū),棧區(qū)的數(shù)據(jù)在執(zhí)行完后自動釋放
? ?return &a;//返回局部變量的地址
}
int main()
{
? ?//接受func函數(shù)的返回值
? ?int* p = func();
? ?cout << *p << endl;//這里顯示錯誤,error
? ?return 0;
}
堆區(qū):
-
由程序員分配釋放,若程序員不釋放,程序結束時由操作系統(tǒng)回收
-
在C++中主要利用new在堆區(qū)開辟內存
示例:
#include<iostream>
using namespace std;
int* func()
{
? ?//利用new關鍵,可以將數(shù)據(jù)開辟到堆區(qū)
? ?//指針 本質是一個局部變量,放在棧上,但是數(shù)據(jù)放在堆區(qū)
? ?int *p = new int(10);
? ?return p;
}
?
int main()
{
? ?//堆區(qū)開辟數(shù)據(jù)
? ?int* a = func();
? ?cout << *a << endl;
? ?return 0;
}
總結: 堆區(qū)數(shù)據(jù)由程序員管理開辟和釋放 堆區(qū)數(shù)據(jù)開辟利用new關鍵字進行開辟內存
new操作符
C++中利用new操作符在堆區(qū)開辟數(shù)據(jù) 堆區(qū)開辟的數(shù)據(jù),由程序員手動開辟,手動釋放。 釋放利用操作符delete
語法:new 數(shù)據(jù)類型
利用new創(chuàng)建的數(shù)據(jù),返回該數(shù)據(jù)對應的類型的指針
示例:
#include<iostream>
using namespace std;
//new的基本語法
int * func()
{
? ?//在堆區(qū)創(chuàng)建整型數(shù)據(jù)
? ?//返回該數(shù)據(jù)類型的指針
? ?int * p = new int(10);
? ?return p;
}
?
void test01()
{
? ?int * p = func();
? ?cout << *p << endl;
? ?//堆區(qū)的數(shù)據(jù)由程序員管理開辟,程序員管理釋放
? ?//如果想釋放堆區(qū)數(shù)據(jù),
? ?delete p;
? ?cout << *p << endl;//非法訪問,數(shù)據(jù)已釋放,error,會出現(xiàn)亂碼
}
?
//在堆區(qū)利用new開辟數(shù)據(jù)
void test02()
{
? ?//創(chuàng)建10個整型數(shù)據(jù)的數(shù)組在堆區(qū)
? ?int * arr = new int[10];//代表數(shù)組有10個元素
? ?for(int i = 0;i < 10; i++)
? {
? ? ? ?arr[i] = i + 100;
? }
? ?for(int i = 0;i < 10; i++)
? {
? ? ? ?cout << arr[i] << " ";
? }
? ?cout << endl;
? ?//釋放堆區(qū)數(shù)組
? ?//釋放數(shù)組的時候,要加[]才可以
? ?delete[] arr;
}
int main()
{
? ?test01();
? ?test02();
? ?return 0;
}
引用
引用C++核心編程引用的基本使用引用注意事項引用做函數(shù)參數(shù)引用函數(shù)返回值引用的本質常量引用
C++核心編程
引用的基本使用
作用:給變量起名
語法:數(shù)據(jù)類型 &別名 = 原名
示例
#include<iostream>
using namespace std;
int main()
{
? ?int a = 10;
? ?int &b = a;
? ?b = 20;
? ?cout << "a = " << a << endl;
? ?cout << "b = " << b << endl;
? ?return 0;
}
a = 20 b = 20
引用注意事項
-
引用必須初始化
-
引用在初始化后,不可以改變
示例
#inlcude<iostream>
using namespace std;
int main()
{
? ?//引用必須初始化
? ?int a = 10;
? ?int &b;//error
? ?int &b = a;
? ?
? ?//引用初始化后,是不能更改引用的
? ?int c = 20;
? ?b = c;//error
? ?cout << "a = " << a << endl;
? ?cout << "b = " << b << endl;
? ?cout << "c = " << c << endl;
return 0;
}
引用做函數(shù)參數(shù)
作用:函數(shù)傳參時,可以利用引用的技術讓形參修飾實參
優(yōu)點:可以簡化指針修改實參
示例
#include<iostream>
using namespace std;
//交換函數(shù)
//值傳遞
void mySwap01(int a,int b)
{
? ?int tmp = a;
? ?a = b;
? ?b = tmp;
? ?cout << "a = " << a << endl;
? ?cout << "b = " << b << endl;//只在這個函數(shù)里面才有效,結束后還給系統(tǒng)
}
?
//指針的地址傳遞
void mySwap02(int* a,int* b)
{
? ?int tmp = *a;
? ?*a = *b;
? ?*b = tmp;
}
?
//引用傳遞
void mySwap03(int &a,int &b)
{
? ?int tmp = a;
? ?a = b;
? ?b = tmp;
}
?
int main()
{
? ?int a = 10;
? ?int b = 20;
? ?mySwap01(a,b);
? ?mySwap02(&a,&b);
? ?mySwap03(a,b);//引用傳遞,形參會修飾實參的
? ?cout << "a = " << a << endl;
? ?cout << "b = " << b << endl;
return 0;
}
引用函數(shù)返回值
作用:引用是可以作為函數(shù)的返回值存在的
注意:不要返回局部變量引用
用法:函數(shù)調用作為左值
示例
#include<iostream>
using namespace std;
?
//不要返回局部變量的引用
int& test01()
{
? ?int a = 10;//局部變量存放在四區(qū)中的棧區(qū)
? ?return a;
}
?
//函數(shù)的調用可以作為左值
int& test02()
{
? ?static int a = 10;//靜態(tài)變量存放在全局區(qū),在程序結束后由系統(tǒng)回收
? ?return a;
}
?
int main()
{
? ?int &ref = test01();
? ?cout << ref << endl;//error,a的內存已經(jīng)釋放,屬于非法訪問
? ?int &ret = test02();
? ?cout << ret <<endl;
? ?test02() = 1000;
? ?cout << ret <<endl;//這里的值ret會改成1000
return 0;
}
引用的本質
本質:引用的本質在C++內部實現(xiàn)是一個指針常量。
示例
#include<iostream>
using namespace std;
?
//發(fā)現(xiàn)是引用,轉化為int* const ref = &a;
void func(int& ref)
{
? ?ref = 100;//ref是引用,轉換為*ref = 100;
}
?
int main()
{
? ?int a = 10;
? ?
? ?//自動轉換為int* const ref = &a;指針常量是指針指向不可改,也說明了為何引用不可更改
? ?int& ref = a;
? ?ref = 20;//內部發(fā)現(xiàn)ref是引用,自動幫我們轉化為*ref = 20;
? ?
? ?cout << "a = " << a << endl;
? ?cout << "ref = " << ref << endl;
? ?
? ?func(a);
return 0;
}
常量引用
作用:常量引用主要用來修飾形微,防止誤操作
在函數(shù)形參列表中,可以加const修飾形參,防止形參改變實參
#include<iostream>
using namespace std;
?
void showValue(const int & ref)
{
? ?ref = 20;//error,無法改變
}
int main()
{
? ?//常量引用
? ?//使用場景:用來修飾形參,防止誤操作
? ?int a = 10;
? ?//int & ref = 10;error 引用必須引用一塊合法的內存空間
? ?const int & ref =10;//這是允許的,編譯器將代碼修改為 int temp = 10; const int & ref = temp;
? ?
? ?int b = 100;
? ?showValue(b);
? ?cout << b << endl;
return 0;
}
類與對象
C++中類與對象的學習
C++面向對象的三大特性為:封裝、繼承、多態(tài)
C++認為萬事萬物皆為對象。對象上有其屬性和行為
例如: 人可以作為對象,屬性有姓名、年齡、身高、體重…… 行為有走、跑、跳、吃飯、唱歌……
車也可以作為對象,屬性有輪胎、方向盤、車燈……行為有載人、放音樂、開啟空調……
具有相同性質的對象,我們可以抽象稱為類,人屬于人類,車屬于車類
封裝
封裝的意義1
封裝是C++面向對象的三大特性之一
封裝的意義:
-
將屬性和行為作為一個整體
-
將屬性和行為加以權限控制
封裝意義1:
在設計類的時候,屬性和行為寫在一起,表現(xiàn)事物
語法:class 類名 { 訪問權限: 屬性 / 行為 };
設計一個圓類
求圓的周長
#include<iostream>
using namespace std;
?
const double PI = 3.14;
//設計一個圓類,求圓的周長
//圓求周長的公式:2 * PI * 半徑
//class代表設計一個類,類后面緊跟著的就是類名稱
class Circle
{
? ?//訪問權限
? ?//公共權限
public:
? ?
? ?//屬性
? ?//半徑
? ?int m_r;
? ?
? ?//行為
? ?//獲取圓的周長
? ?double calculateZC()
? {
? ? ? ?return 2 * PI * m_r;
? }
? ?
};
?
int main()
{
? ?//通過圓類 創(chuàng)建一個具體的圓(對象)
? ?//實例化 (通過一個類 創(chuàng)建一個對象的過程)
? ?Circle c1;
? ?//對圓對象的屬性進行賦值
? ?c1.m_r = 10;
? ?cout << "圓的周長" << c1.calculateZC() << endl;
? ?return 0;
}
設計一個學生類
屬性有姓名學號,可以給姓名學號賦值,可以顯示學生姓名和學號
#include<iostream>
#include<string>
using namespace std;
?
class Student
{
public:
? ?string m_Name;
? ?int m_Id;
? ?void showStudent()
? {
? ? ? ?cout << "姓名:" << m_Name << "\t" << "學號:" << m_Id << endl;
? }
};
?
int main()
{
? ?//實例化對象
? ?Student s1;
? ?//s1對象進行屬性賦值操作
? ?s1.m_Name = "zhangsan";
? ?s1.m_Id = 12345;
? ?s1.showStudent();
? ?
? ?//實例化對象
? ?Student s2;
? ?//s1對象進行屬性賦值操作
? ?s2.m_Name = "lisi";
? ?s2.m_Id = 12346;
? ?s2.showStudent();
? ?return 0;
}
亦可以用下面的方式對類進行賦值操作
#include<iostream>
#include<string>
using namespace std;
?
class Student
{
public:
? ?//類中的屬性和行為統(tǒng)一稱為成員
? ?string m_Name;
? ?int m_Id;
public:
? ?void showStudent()
? {
? ? ? ?cout << "姓名:" << m_Name << "\t" << "學號:" << m_Id << endl;
? }
? ?void setName(string name)
? {
? ? ? ?m_Name = name;
? }
? ?void setId(int id)
? {
? ? ? ?m_Id = id;
? }
};
?
int main()
{
? ?//實例化對象
? ?Student s1;
? ?//s1對象進行屬性賦值操作
? ?s1.setName("zhangsan");
? ?s1.setId(12345);
? ?s1.showStudent();
? ?return 0;
}
封裝的意義2
類在設計時,可以吧屬性和行為放在不同的權限下,加以控制
訪問權限有三種:
-
public 公共權限
-
protected 保護權限
-
private 私有權限
示例
#include<iostream>
#include<string>
using namespace std;
//訪問權限
//公共權限public 成員類內可以訪問 類外也可以訪問
//保護權限protected 成員類內可以訪問 類外不可以訪問
//私有權限private 成員類內可以訪問 類外不可以訪問
class Person
{
public:
? ?//公共權限
? ?string m_Name;
protected:
? ?//保護權限
? ?string m_Car;
private:
? ?//私有權限
? ?int m_Password;
public:
? ?void func()
? {
? ? ? ?m_Name = "zhangsan";
? ? ? ?m_Car = "Tractor";
? ? ? ?m_Password = 123456;
? }
? ?void func2()
? {
? ? ? ?cout << "1." << m_Name << "\t" << "2." << m_Car << "\t" << "3." << m_Password << endl;
? }
};
?
int main()
{
? ?//實例化具體對象
? ?Person p1;
? ?//p1.m_Car = "Benz";//error,保護權限內容在類外是訪問不到的
? ?//p1.m_Password = 123;error,保護權限內容在類外是訪問不到的
? ?p1.func();
? ?p1.m_Name = "Lisi";
? ?p1.func2();
? ?return 0;
}
struct和class的區(qū)別
在C++中struct和class唯一的區(qū)別就在于默認的訪問權限不同 區(qū)別:
-
struct 默認權限為公共
-
class 默認權限為私有
#include<iostream>
using namespace std;
?
class C1
{
? ?int m_A;//默認權限是私有權限
};
?
struct C2
{
? ?int m_A;//默認權限是公共權限
};
?
int main()
{
? ?C1 c1;
? ?c1.m_A = 10;//error
? ?struct C2 c2;
? ?c2.m_A = 10;//正確的
? ?return 0;
}
成員屬性設置為私有
優(yōu)點1:將所有成員屬性設置為私有,可以自己控制讀寫權限
優(yōu)點2:對于寫權限,我們可以檢測數(shù)據(jù)的有效性
示例
#include<iostream>
#include<string>
//成員屬性設置為私有
//可以自己控制讀寫權限
//對于寫權限可以檢測數(shù)據(jù)的有效性
using namespace std;
int main()
{
? ?return 0;
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-416715.html
到了這里,關于進一步了解C++函數(shù)的各種參數(shù)以及重載,了解C++部分的內存模型,C++獨特的引用方式,巧妙替換指針,初步了解類與對象。滿滿的知識,希望大家能多多支持的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!