日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C++核心编程(一)

發(fā)布時間:2023/11/28 生活经验 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++核心编程(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C++ 核心編程

本系類列博客都是根據(jù)黑馬的C++視頻做的筆記。
本階段主要針對C++面向?qū)ο缶幊碳夹g(shù)做詳細記錄,探討C++中的核心和精髓。

1、內(nèi)存分區(qū)模型

C++程序在執(zhí)行時,將內(nèi)存大方向劃分為4個區(qū)域

  • 代碼區(qū):存放函數(shù)體的二進制代碼,由操作系統(tǒng)進行管理
  • 全局區(qū):存放全局變量和靜態(tài)變量以及常量
  • 棧區(qū):由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量等
  • 堆區(qū):由程序員分配和釋放,若程序員不釋放,程序結(jié)束時由操作系統(tǒng)回收

內(nèi)存四區(qū)的意義
不同區(qū)域存放的數(shù)據(jù),賦予不同的生命周期,給我們更大的靈活編程

1.1 程序運行前

在程序編譯后,生成了exe可執(zhí)行程序,未執(zhí)行該程序前分為兩個區(qū)域:

  • 代碼區(qū)
    存放CPU執(zhí)行的機器指令
    代碼區(qū)是共享的,共享的目的是對于頻繁被執(zhí)行的程序,只需要在內(nèi)存中有一份代碼即可
    代碼區(qū)是只讀的,使其只讀的原因是防止程序意外地修改了它的指令
  • 全局區(qū)
    全局變量和靜態(tài)變量存放于此
    全局區(qū)還包含了常量區(qū),字符串常量和其他常量也存放于此
    該區(qū)域的數(shù)據(jù)在程序結(jié)束后由操作系統(tǒng)釋放
    const修飾的變量也是常量

示例

#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()
{// 全局區(qū)// 全局變量、靜態(tài)變量、常量// 創(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 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 << "字符串'Hello world'的地址為:" << (int)&("Hello world") << endl;// const修飾的變量// const 修飾的全局變量,const修飾的局部變量cout << "全部常量c_g_a的地址為:" << (int)&c_g_a << endl;cout << "全部常量c_g_b的地址為:" << (int)&c_g_b << endl;// 局部const int c_l_a = 10; // c const; g global l localconst 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;}


總結(jié)

  • C++中在程序運行之前分為全局區(qū)代碼區(qū)
  • 代碼區(qū)特點是共享只讀
  • 全局區(qū)中存放全局變量、靜態(tài)變量、常量
  • 常量區(qū)中存放const修飾的全局變量字符串常量

1.2 程序運行后

1.2.1 棧區(qū)

由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量等
注意事項:不要返回局部變量的地址,棧區(qū)開辟的數(shù)據(jù)由編譯器自動釋放

示例

#include <iostream>using namespace std;// 棧區(qū)數(shù)據(jù)注意事項,不要反悔局部變量的地址
// 棧區(qū)的數(shù)據(jù)由編譯器管理開辟和釋放int* func(int b)	// 形參數(shù)據(jù)也會保留在棧區(qū)	
{int a = 10; // 局部變量,存放在棧區(qū),棧區(qū)的數(shù)據(jù)在函數(shù)執(zhí)行完成之后自動釋放return &a; // 返回局部變量的地址
}int main()
{// 接受func函數(shù)的返回值int* p = func(2);cout << *p << endl;	// 本次可能打印正確的數(shù)據(jù),編譯器做了保留cout << *p << endl;	// 第二次這個數(shù)據(jù)就不再保留了return 0;
}

1.2.3 堆區(qū)

  • 由程序員分配釋放,若程序員不釋放,程序結(jié)束時由操作系統(tǒng)回收
  • 在c++中主要利用new在堆去開辟內(nèi)存

示例

#include <iostream>
using namespace std;int* func()
{// 利用new關(guān)鍵字可以將數(shù)據(jù)開辟到堆區(qū)// new 關(guān)鍵字返回的是地址// 指針本質(zhì)也是一個變量(局部變量),放在棧上,指針指向的數(shù)據(jù)是放在堆區(qū)int *a = new int(10);return a;
}int main()
{// 在堆區(qū)中開辟數(shù)據(jù)int* p = func();cout << *p << endl;cout << *p << endl;cout << *p << endl;return 0;
}

總結(jié)
堆區(qū)的數(shù)據(jù)由程序員管理開辟和釋放
堆區(qū)的數(shù)據(jù)利用關(guān)鍵字new進行開辟內(nèi)存

1.3 new操作符

C++中利用new操作符在堆區(qū)開辟數(shù)據(jù)
堆區(qū)開辟的數(shù)據(jù),有程序員手動開辟,手動釋放利用操作符delete
語法:new 數(shù)據(jù)類型
利用new創(chuàng)建的數(shù)據(jù)會返回對應(yīng)數(shù)據(jù)類型的指針

示例

#include <iostream>
using namespace std;int* func()
{// 在堆區(qū)創(chuàng)建整型數(shù)據(jù)// new 返回的是 該數(shù)據(jù)類型的指針int* p = new int(10);return p;
}void test01()
{int* p = func();cout << *p << endl;cout << *p << endl;// 堆區(qū)的數(shù)據(jù)由程序員管理,包括開辟和釋放// 釋放堆區(qū)中的數(shù)據(jù),利用關(guān)鍵字newdelete p;//cout << *p << endl;	// 內(nèi)存已經(jīng)被釋放,再次訪問就是非法操作,就會報錯
}// 2、在堆區(qū)利用new開辟一個數(shù)組
void test02()
{// 創(chuàng)建10整型的數(shù)據(jù)的數(shù)組,在堆區(qū)int* arr = new int[10];	// 10代表數(shù)組里面有10個元素for (int i = 0; i <10; i++){arr[i] = i + 1;}for (int j= 0; j < 10; j++){cout << arr[j] << endl;}// 釋放堆區(qū)數(shù)組// 釋放數(shù)組的傷害,要加 []才可以delete[] arr;}
int main()
{//test01();test02();return 0;
}

注意

數(shù)組的釋放需要加[]才可以,例如:delete[] arr

2、引用

2.1 引用的基本使用

**作用:**給變量取別名
**語法:**數(shù)據(jù)類型 &別名 = 原名

圖示:

示例

#include <iostream>using namespace std;int main()
{// 引用的基本語法// 數(shù)據(jù)類型 &別名 = 原名int a = 10;// 創(chuàng)建引用int& b = a;cout << "a = " << a << endl;cout << "b = " << b << endl;// 修改值b = 100;cout << "a = " << a << endl;cout << "b = " << b << endl;return 0;
}

2.2 引用注意事項

  • 引用必須要初始化
  • 引用一旦初始化就不可以更改

圖示

示例

#include <iostream>
using namespace std;int main()
{int a = 10;// 1. 引用必須初始化//int& b;	// 錯誤,必須要初始化int& b = a;// 2、 引用在初始化后,不可以改變int c = 20;b = c;	// 此為賦值操作,并不是更改引用cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;}

2.3 引用做函數(shù)的參數(shù)

作用: 函數(shù)傳參是,可以利用引用的技術(shù)讓形參修飾實參
優(yōu)點: 可以簡化指針修改實參

示例

#include<iostream>
using namespace std;// 1、值傳遞
void mySwap01(int a, int b)
{int temp = a;a = b;b = temp;
}// 2、地址傳遞
void mySwap02(int* a, int* b)
{int temp = *a;*a = *b;*b = temp;}// 3、 引用傳遞
void mySwap03(int& a, int& b)
{int temp = a;a = b;b = temp;
}int main()
{int a = 10;int b = 20;cout << "a = " << a << endl;cout << "b = " << b << endl;// mySwap01(a, b);		// 未交換// mySwap02(&a, &b);	// 已經(jīng)交互mySwap03(a, b);		// 已經(jīng)交換cout << "a = " << a << endl;cout << "b = " << b << endl;return 0;
}

總結(jié):通過引用參數(shù)產(chǎn)生的效果和按地址傳遞是一樣的。引用的語法更清楚簡單。

2.4 引用做函數(shù)的返回值

作用: 引用是I可以作為函數(shù)的返回值存在的

注意:不要返回局部變量引用
用法:函數(shù)調(diào)用作為左值

示例

#include<iostream>
using namespace std;// 引用做函數(shù)的返回值
// 1、不要反悔局部變量的引用
int& test01()
{int a = 10;	// 局部變量存放在四區(qū)中的棧區(qū)return a;
}// 2、函數(shù)調(diào)用可以可以作為左值
int& test02()
{static int a = 10;	// 靜態(tài)變量,存放在全局區(qū),在程序結(jié)束后釋放return a;
}int main()
{//int& ref = test01();//cout << "ref = " << ref << endl;	// 第一次 正確的數(shù)據(jù) 編譯器做了保留//cout << "ref = " << ref << endl;	// 第二次 錯誤結(jié)果 a的內(nèi)存已經(jīng)釋放 無權(quán)操作int& ref2 = test02();cout << "ref2 = " << ref2 << endl;cout << "ref2 = " << ref2 << endl;// 左值test02() = 1000;cout << "ref2 = " << ref2 << endl;cout << "ref2 = " << ref2 << endl;return 0;
}

2.5 引用的本質(zhì)

本質(zhì): 引用的本質(zhì)在c++中就是一個指針常量
講解示例:

// 發(fā)現(xiàn)是引用,轉(zhuǎn)換為 int* const ref = &a;
void func(int& ref)
{ref = 200;
}int main()
{int a = 10;// 自動轉(zhuǎn)換為 int* const ref = &a;指針常量是指針指向不可更改int& ref = a;ref = 20; // 內(nèi)部發(fā)現(xiàn)ref是引用,自動幫我們轉(zhuǎn)換為 *ref = 20;cout << "a = " << a << endl;cout << "ref = " << ref << endl;func(a);return 0;}

圖示

結(jié)論:C++推薦使用引用計數(shù),因為語法方便,引用本質(zhì)就是指針常量,但是所有的指針操作編譯器都幫我們做了。

2.6 常量引用

作用: 主要用于修飾形參,防止誤操作
在函數(shù)形參列表中,可以加const修飾形參,防止形參改變實參

示例:


// 打印數(shù)據(jù)
void showValue(const int& val)
{// val = 10000;	// 防止被修改cout << "val = " << val << endl;
}int main()
{// 常量引用// 使用場景:用來修飾形參,防止誤操作int a = 10;// 加上const之后,編譯器將代碼修改為 int temp = 10; const int& ref = temp;// 如果沒有const 也即:int& ref = 10; 為錯誤語法const int& ref = 10;	// 引用必須引用一塊合法的內(nèi)存空間// ref = 20;	// 加入const之后變?yōu)橹蛔x,不可寫showValue(a);return 0;
}

3、函數(shù)提高

3.1 函數(shù)默認參數(shù)

在C++中,函數(shù)的形參列表中的形參是可以有默認值得。
語法:返回值類型 函數(shù)名(參數(shù) = 默認值){}

示例:

#include<iostream>
using namespace std;// 函數(shù)默認參數(shù)
int sum(int a = 0, int b = 0, int c = 0)
{return a + b + c;
}// 注意事項:、
// 1、如果某個位置已經(jīng)有了默認參數(shù),那么這個位置之后,都必須要有默認值
// 2、如果函數(shù)聲明有默認參數(shù),函數(shù)實現(xiàn)就不能有默認參數(shù),如果函數(shù)實現(xiàn)有默認參數(shù),聲明就不能有參數(shù)int func(int a = 10, int b = 20, int c = 30);
int func(int a, int b, int c)
{return a + b + c;
}int main()
{cout << sum() << endl;cout << sum(10, 20) << endl;cout << sum(10, 20, 20) << endl;cout << func(20, 100) << endl;return 0;
}

注意: 如果某個位置有了默認參數(shù),后面的參數(shù)必須都要設(shè)定默認值,例如:int sum(int a = 0, int b)為錯誤使用。
注意: 如果函數(shù)聲明有默認參數(shù),函數(shù)實現(xiàn)就不能有默認參數(shù),如果函數(shù)實現(xiàn)有默認參數(shù),聲明就不能有參數(shù)
結(jié)論: 如果傳入?yún)?shù),就用傳入的值,如果沒有,就是用默認值

3.2 函數(shù)占位符

C++中函數(shù)的形參列表里面可以有占位參數(shù),用來占位,調(diào)用函數(shù)時必須填補該位置

語法: 返回值類型 函數(shù)名(數(shù)據(jù)類型){}
在現(xiàn)階段函數(shù)的占位參數(shù)存在意義不大,但是后面的課程中會用到該特性

示例:


// 占位參數(shù)
// 返回值類型 函數(shù)名(數(shù)據(jù)類型) {}// 目前階段的占位參數(shù) 還用不到,后面知識點中會用到
// 占位參數(shù)還可以有默認參數(shù)
void func(int a, int = 10)
{cout << "this is func " << endl;
}int main()
{// 如果不給第二個占位參數(shù)傳值,則報錯func(10, 10);return 0;
}

3.3 函數(shù)的重載

3.3.1 函數(shù)重載概述

作用: 函數(shù)名可以相同,提高復(fù)用性

函數(shù)重載滿足條件:

  • 同一個作用域下
  • 函數(shù)名相同
  • 函數(shù)參數(shù)的類型不同、個數(shù)不同、或者順序不同

注意: 函數(shù)的返回值不可以作為函數(shù)重載的條件

示例:

#include<iostream>
using namespace std;// 函數(shù)重載
// 可以讓函數(shù)名相同,提高復(fù)用性// 函數(shù)重載條件
// 1、同一個作用域
// 2、同一個函數(shù)名
// 3、參數(shù)的類型、個數(shù)以及類型不同
void func()
{cout << "func 的調(diào)用!" << endl;
}void func(int a)
{cout << "func 的調(diào)用!!" << endl;
}void func(double a)
{cout << "func double 的調(diào)用!!" << endl;
}void func(int a, double b)
{cout << "func(int, double) 的調(diào)用!!" << endl;
}void func(double b, int a)
{cout << "func(double, a) 的調(diào)用!!!" << endl;
}// 函數(shù)的返回值不可以作為重載條件
int main()
{// 如果不給第二個占位參數(shù)傳值,則報錯func();func(20);func(2.1);func(10.2, 20);func(20, 10.2);return 0;
}

3.3.2 函數(shù)重載注意事項

  • 引用作為重載條件
  • 函數(shù)重載遇到函數(shù)默認參數(shù)

示例:

#include<iostream>
using namespace std;// 函數(shù)重載的注意事項
// 1、應(yīng)用作為重載的條件
void func(int &a)	// int &a = 10; 不合法
{cout << "func(int &a) 的調(diào)用!" << endl;
}void func(const int &a)		// const int &a = 10 合法
{cout << "func(const int& a) 的調(diào)用!" << endl;
}// 2、函數(shù)重載碰到默認參數(shù)
void func2(int a)
{cout << "func2(int a) 的調(diào)用!" << endl;
}// 默認參數(shù)會導(dǎo)致二義性,和上面的函數(shù)有沖突
//void func2(int a, int b = 20)
//{
//	cout << "func2(int a = 2) 的調(diào)用!" << endl;
//}// 2、函數(shù)重載遇到默認參數(shù)
// 函數(shù)的返回值不可以作為重載條件
int main()
{// 如果不給第二個占位參數(shù)傳值,則報錯int a = 10;func(a);	// 調(diào)用的是:func(int& a)函數(shù)func(10);	// 調(diào)用的是:func(const int& a)函數(shù)func2(2);return 0;
}

注意: 函數(shù)形參有默認值時,可能會導(dǎo)致函數(shù)二義性,也即調(diào)用函數(shù)不知道該調(diào)用哪一個函數(shù),應(yīng)當盡量避免這種情況。

總結(jié)

以上是生活随笔為你收集整理的C++核心编程(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。