wordpress站內(nèi)優(yōu)化網(wǎng)絡營銷評價的名詞解釋
目錄
知識點1 C++的概述
1 C++的特征
2 C++程序的編輯、編譯和執(zhí)行
3 第一個C++源程序
4 面向?qū)ο蟪绦蛟O計思想
4.1 面向?qū)ο蟪绦蛟O計思想初始
4.2 面向?qū)ο蟪绦蛟O計思想的核心
知識點2 C++對C的擴展
1 作用域訪問運算符(::)
2 名稱空間域
2.1 創(chuàng)建名稱空間域
2.2 已有名稱空間域成員訪問
2.3 多文件名稱空間域創(chuàng)建
3 語法檢測增強
3.1 同名未初始化全局變量
3.2 數(shù)據(jù)類型語法增強
3.3 新增bool數(shù)據(jù)類型
3.4 函數(shù)的參數(shù)問題
3.5 三目運算符增強
3.6 const 增強
3.7 struct增強
4 引用(reference)
4.1 引用定義
4.2 數(shù)組的引用
4.3 函數(shù)中的引用
4.4 指針的引用
4.5 常量的引用
4.6 引用和指針的關(guān)系
知識點3 函數(shù)重載和函數(shù)默認參數(shù)
1 函數(shù)重載
2 函數(shù)的默認參數(shù)值
3 函數(shù)的占位參數(shù)
4 函數(shù)重載和函數(shù)默認參數(shù)值同時使用
知識點4 內(nèi)聯(lián)函數(shù)
1 內(nèi)聯(lián)函數(shù)的定義
2 內(nèi)聯(lián)函數(shù)編譯
3 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別
知識點5 C++中的輸入輸出
知識點6 字符串類
知識點7 C++內(nèi)存管理
1 C語言中存管理方式
2 C++內(nèi)存管理
2.1 運算符new和delete的使用
2.2 new和malloc區(qū)別
一, C++的概述
1 C++的特征
????????所謂的C++,是對C的擴展;c++語言在 c 語言的基礎上添加了面向?qū)ο缶幊毯头盒途幊痰闹С帧?/p>
1. C++ 繼承C語言的思想:具備C語言面向過程的思想,語言高效、簡潔,具有可移植性;
2. C++ 具備面向?qū)ο蟪绦蛟O計思想;
3. 模板支持的泛型編程;
2 C++程序的編輯、編譯和執(zhí)行
????????由于C++繼承了C語言的特性,也就是說C語言程序可以作為C++程序。
????????在Linux系統(tǒng)中,GNU工具中提供了C++編譯器:g++,整個程序的編譯過程依然分為4個階段:
????????整體編譯:g++ 源程序文件 可以使用-o指定輸出可執(zhí)行文件名稱,如果未指定則默認生成可執(zhí)行文件 a.out
1. 預處理階段
????????實現(xiàn)預處理指令的執(zhí)行:頭文件的展開、宏(標識符常量和標識符語句)定義的替換、語句的選擇編譯
g++ -E hello.c -o hello.i
2. 編譯階段
????????實現(xiàn)預處理后程序語法的檢測,并生成匯編指令;
????????g++ -S hello.i -o hello.s
3. 匯編階段
????????實現(xiàn)將匯編指令翻譯為二進制機器指令;
????????g++ -C hello.s -o hello.o
4. 鏈接階段
????????實現(xiàn)將程序中所有的.o文件進行鏈接、依賴庫鏈接和啟動程序連接;
????????g++ hello.o -o hello
3 第一個C++源程序
#include <iostream> /* 添加頭文件:標準庫頭文件(提供標準輸入輸出流) */
using namespace std; /* 做名稱空間域聲明,聲明后可以直接對名稱空間域中的函數(shù)和變量符號進行直接訪問 */int main()
{/* cout:標準輸出流,std::cout;endl:是換行標識,定義在std::endl; */cout << "hello world" << endl; /* 等價于:printf("hello world"); */return 0;
}
1. C++源程序后綴:
????????源程序文件可以使用.c、.cxx、.cpp
????????????????在C++源程序設計過程中,一般情況將源程序文件后綴設置為.cpp(可移植性更好)。
2. 頭文件的包含:
3. namespace 做名稱空間域的聲明
????????在C++中新增名稱空間域,避免同一個程序中的多個同名變量和函數(shù)的訪問。
4. cout和endl
????????cout是標準C++庫中所提供的標準輸出流,在名稱空間域std中定義;
????????endl是標準C++庫中提供的換行標識,同時刷新緩沖區(qū);在名稱空間域std中定義;
4 面向?qū)ο蟪绦蛟O計思想
4.1 面向?qū)ο蟪绦蛟O計思想初始
1. 面向過程程序設計思想
????????所謂的面向過程程序設計思想,指的是以解決問題的思路為步驟,按照步驟先后順序依次執(zhí)行逐一解決問題的過程。
????????面向過程編程思想的核心:功能分解,自頂向下,逐層細化(程序=數(shù)據(jù)結(jié)構(gòu)+算法)。
2. 面向過程程序設計思想
????????所謂面向?qū)ο缶幊?#xff08;Object-Oriented Programming)簡稱 OOP 技術(shù)
????????任何類對象都具有一定的屬性和操作行為,可以將屬性抽象為具體數(shù)據(jù)類型變量和常量存儲、將操作行為抽象為具體的函數(shù)及其算法。
????????所謂的對象 = 數(shù)據(jù)結(jié)構(gòu) + 算法;
????????程序 = 對象 + 對象 + ……
4.2 面向?qū)ο蟪绦蛟O計思想的核心
1. 封裝
????????所謂的封裝,實質(zhì)是將相同的對象的屬性抽象為具體數(shù)據(jù)類型的成員變量和對象的行為抽象為具體的成員函數(shù)。并同時使用訪問權(quán)限修飾封裝的過程。
2. 繼承
????????所謂的繼承,表示類與類之間的關(guān)系,在構(gòu)造新的類的時候,如果新構(gòu)造的類對象和原有類型對象之間滿足:is關(guān)系的時候,讓新構(gòu)造類對象繼承原有類對象的屬性和行為的過程。
????????繼承可以有效實現(xiàn)代碼重用,避免代碼和數(shù)據(jù)冗余。
3. 多態(tài)
????????所謂的多態(tài),指的是“一個接口,多種方法”。在程序運行過程中決定接口的具體行為。
二, C++對C的擴展
1 作用域訪問運算符(::)
????????在C++中增加了作用域訪問運算符(::),可以修飾函數(shù)和變量的作用域,以實現(xiàn)在同一個程序中對不同作用域下同名成員變量和成員函數(shù)的訪問。
具體的語法格式:
????????作用域::函數(shù)和變量符號
????????????????1) 作用域可以是全局作用域、具備作用域、名稱空間域和類域;
????????????????2) 函數(shù)和變量符號、可以是C函數(shù)和變量、類成員函數(shù)和變量以及名稱空間域成員函數(shù)和變量;
1. 全局變量和局部變量
????????作用域省略:此時默認作用為全局域且僅為全局域;
????????作用域和作用域訪問運算符省略:模塊內(nèi)使用,
????????????????1) 模塊內(nèi)有定義,此時訪問的模塊內(nèi)域中的函數(shù)和變量;
????????????????2) 模塊內(nèi)未定義,此時訪問全局的函數(shù)和變量;
#include <stdio.h>int a = 1; /* 定義一個全局作用的變量 */int main()
{int a = 3; /* 在局部模塊內(nèi)定義了和全局同名的局部變量和函數(shù),局部覆蓋全局 *//* 省略作用域和作用域運算符的時候,模塊內(nèi)有局部變量則覆蓋全局變量,訪問的是局部變量,否則模塊內(nèi)沒有局部變量則訪問全局變量 */printf("a = %d\n", a); /* 只省略作用域而未省略作用訪問運算符的時候,默認作用域為全局域且只能為全局域 */printf("::a = %d\n", ::a);
}
2. 作用域為類域或者名稱空間域
????????所謂的變量和函數(shù)是指定類域或者名稱空間域中的成員和變量;
#include <stdio.h>int a = 1;namespace myspace {int a = 4; /* 定義變量a的作用域為myspace名稱空間 */};int main()
{int a = 3;printf("a = %d\n", a); printf("::a = %d\n", ::a);/* 在作用域和作用域運算符不省略的時候,作用域為名稱空間域和類域,所訪問的是指定作用域中的變量和函數(shù) */printf("myspace::a = %d\n", myspace::a);
}
2 名稱空間域
????????所謂名稱空間域,指的是將特殊的符號常量、變量、函數(shù)、結(jié)構(gòu)體、枚舉等數(shù)據(jù)量,使用關(guān)鍵字namespace的名稱空間域進行封裝,此時數(shù)據(jù)符號只能在名稱空間域中和通過名稱空間域進行訪問訪問,從而解決程序中因為同名導致訪問函數(shù)或者變量沖突的問題。名稱空間域也稱為命名空間/名字空間/名稱空間
2.1 創(chuàng)建名稱空間域
1. 語法格式
namespace 名稱空間域的名稱 {/* 符號常量、變量、函數(shù)、結(jié)構(gòu)體、枚舉等 */
}
2. 創(chuàng)建名稱空間域?qū)嵗?/p>
????????a) 創(chuàng)建有名命名空間
#include <stdio.h>int a = 3; /* a作用域為全局域 */namespace myspace {enum {Frist = 1,second};/* 名稱空間域中定義成員變量 */int a = 5; /* C++中增加名稱空間域,a的作用域為名稱空間域:可以在名稱空間域內(nèi)訪問,也可以通過名稱空間域訪問 *//* 名稱空間域中定義和聲明成員函數(shù) */void show(void) {printf("myspace -> a = %d, second = %d\n", a, second); /* 在名稱空間域內(nèi)訪問 */}/* 名稱空間域中聲明成員函數(shù),在名稱空間域外實現(xiàn)定義 */void test(void);
}/* 在名稱空間域外部實現(xiàn)名稱空間域中函數(shù)的定義 */
void myspace::test(void)
{printf("myspace::test()\n");
}/* 名稱空間域具有開放性:如果新創(chuàng)建的名稱空間域已經(jīng)存在,則此時是在原同名名稱空間域中新增成員*/
namespace myspace {int b = 1;
}/* 名稱空間域可以嵌套創(chuàng)建 */
namespace myspace {/* 在myspace名稱空間域中創(chuàng)建Aspace名稱空間域 */namespace Aspace {int a = 33;}/* 在myspace名稱空間域中創(chuàng)建Bspace名稱空間域 */namespace Bspace {int a = 44;}
}void create_namespace(void)
{/* 名稱空間域的創(chuàng)建只能全局創(chuàng)建,不能局部創(chuàng)建 */namespace A { /* error:‘namespace’ definition is not allowed here */int a = 111;}
}int main()
{int a = 4; /* 作用域為局部作用域,只能在main函數(shù)模塊內(nèi)訪問 */printf("myspace::a = %d\n", myspace::a); /* 通過名稱空間域訪問名稱空間域中所定義的變量 */myspace::show();
// printf("second = %d\n", second); /* error, */myspace::test();printf("myspace::b = %d\n", myspace::b);printf("myspace::Aspace::a = %d, myspace::Bspace::a = %d\n", myspace::Aspace::a, myspace::Bspace::a);
}
b) 創(chuàng)建無名命名空間
#include <iostream>
using namespace std;int a = 3;
/* 創(chuàng)建無名命名空間域:* 無名命名空間中的成員只能在當前文件中訪問,相當于使用s
tatic修飾;* 如果成員符號和全局變量或者函數(shù)等符號相同,訪問出現(xiàn)異常*/
namespace {int a = 4;int b = 5;
}int main()
{//cout << a << endl; /* error,此時的變量可以訪問到全局變量a和無名命名空間中的a */cout << b << endl;
}
2.2 已有名稱空間域成員訪問
????????名稱空間域中成員訪問
????????1) 使用作用域訪問運算符訪問:
????????????????名稱空間域::成員變量
????????????????名稱空間域::成員函數(shù)();
???????std::cout << "namespace" << std::endl;/* 訪問std名稱空間域中的cout和endl */
????????2) 先聲明名稱空間域,然后直接符號訪問
using namespace std; /* 對整個名稱空間域進行聲明 */cout << "namespace" << endl; /* 已聲明名稱空間域中的符號可以直接使用符號訪問 */
3) 聲明名稱空間域中的符號,然后直接符號訪問
using std::cout; /* 對名稱空間域中的單個符號進行聲明 */cout << "namespace" << std::endl; /* 已聲明符號可以直接訪問,未聲明符號需要通過作用域訪問運算符訪問 */
2.3 多文件名稱空間域創(chuàng)建
在實際應用過程中,可能多個文件中的成員在同一個名稱空間域中,在創(chuàng)建空間域的時候注意:
????????1) 對于名稱空間域中的成員函數(shù)和成員變量的定義不能在頭文件中定義,只能在源程序中定義,否則出現(xiàn)重復定義;
????????2) 在頭文件中創(chuàng)建名稱空間域的時候,名稱空間域中只能用于函數(shù)的聲明。
????????3) 名稱空間域中成員變量只能在源文件中定義,此時的作用只能作用域所定義的文件中名稱空間域中;
1. 名稱空間域的創(chuàng)建的頭文件:myspace.h
#ifndef _MYSPACE_H_
#define _MYSPACE_H_#include <iostream>
using namespace std;/* 創(chuàng)建名稱空間域 */
namespace myspace {/* 在名稱空間域中進行成員函數(shù)的聲明 */void test(void);
# if 0/* 在頭文件中做成員變量和函數(shù)的定義,可能出現(xiàn)重復定義錯誤 */void show(){cout << "myspace::show()" << endl;}int a;
#endif
}#endif
2. 源程序文件:myspace.cpp
#include <iostream>
#include "myspace.h"
using namespace std;/* 定義名稱空間域中的成員函數(shù) */
void myspace::test(void)
{cout << "myspace::test(void)" << endl;
}namespace myspace {int b = 34;
}
3. 應用程序:app.cpp
#include <iostream>
#include "myspace.h"
using namespace std;
using namespace myspace;namespace myspace {int c = 112;
}int main()
{test();
#if 0cout << "a = " << a << endl;cout << b << endl;cout << myspace::b << endl; /* error:只能在定義源程序文件中訪問 */
#endifcout << c << endl;
}
3 語法檢測增強
3.1 同名未初始化全局變量
????????在C語言語法中,同名變量的出現(xiàn)表示變量的聲明;而在C++語言中,同名變量的出現(xiàn)表示未重復定義;
#include <stdio.h>int a = 34;
/* 同名未初始化全局變量* 在C語言程序中,如果出現(xiàn)同名未初始化全局變量則表示全局變量的聲明* 在C++語言程序中,如果出現(xiàn)同名未初始化全局變量則表示全局變量重復定義出現(xiàn)語法錯誤,*/
int a; int main()
{printf("a = %d\n", a);
}
3.2 數(shù)據(jù)類型語法增強
#include <stdio.h>int main()
{int a = 0x12345678;char c = a;/* 小數(shù)據(jù)類型指針指向大數(shù)據(jù)類型空間:* C語言中,語法警告;C++中語法錯誤*/char *p = &a;
}
3.3 新增bool數(shù)據(jù)類型
????????在C語言中所使用的bool數(shù)據(jù)類型不能訪問,需要添加頭文件#include <stdbool.h>才能訪問;也就是說在C標準庫中未聲明bool數(shù)據(jù)類型,在C標準庫之外進行bool數(shù)據(jù)類型的聲明。
????????在C++語言中,直接新增bool數(shù)據(jù)類型及其數(shù)據(jù)符號true和false;可以直接訪問。
3.4 函數(shù)的參數(shù)問題
#include <stdio.h>
/* 在函數(shù)聲明和定義的時候,沒有形參列表(也沒有void)的時候:* 在C語言中,表示為可變形參,在函數(shù)調(diào)用的時候,傳遞的參數(shù)個數(shù)和參數(shù)的數(shù)據(jù)類型都是可變的(傳遞任意個數(shù)的任意數(shù)據(jù)類型實參數(shù)據(jù)值賦值給形參);但是函數(shù)無形參接收。* 在C++中,表示函數(shù)無形參列表,形參列表等價于void;在函數(shù)調(diào)用的時候不能傳遞參數(shù)值。*/
void test()
{}/* 在函數(shù)聲明和定義的時候,函數(shù)的形參列表中的形參只有形參變量名,而沒有形參數(shù)據(jù)類型* 在C語言中,無語法錯誤,默認將形參數(shù)據(jù)類型為int數(shù)據(jù)類型變量;* 在C++中,語法錯誤。*/
void test1(a)
{}int main()
{test();test('a');test("test");test(1,2,3,4,5);test1(2);test1(2, 3); test1("abc");
}
3.5 三目運算符增強
1. 左值和右值
????????在含有賦值運算符的表達式中,所謂的左值指的是賦值運算符左邊的變量及其表達式稱為左值,左值一定是可以被修改的量;所謂的右值指的是賦值運算符右邊的變量、常量及其表達式值。
2. 三目運算符
????????條件表達式 ?表達式1 :表達式2;
????????????????執(zhí)行過程:執(zhí)行條件對表達式的結(jié)果進行判斷
????????????????1) 如果結(jié)果為true,則執(zhí)行表達式1;
????????????????2) 否則如果結(jié)果為false,則執(zhí)行表達式2;
3. C和C++中的三目運算符
????????三目運算符在C語言中,表達式1和表達式2不能作為左值,而在C++中對表達式1和表達式2變量進行引用作為左值。
3.6 const 增強
1. C語言中的const變量
????????const修飾的變量為只讀變量,不可以直接修改,可以使用指針做間接修改const修飾變量的值。
#include <stdio.h>int main()
{const int a = 3; /* 給變量a分配內(nèi)存空間,a訪問權(quán)限為 read-only,不能直接通過變量a修改存儲空間的數(shù)據(jù)值 */int *p = &a; /* p存儲變量a存儲空間地址,可以通過指針變量p間接修改a存儲空間數(shù)據(jù)值 */printf("a = %d, *p = %d\n", a, *p);
// a = 5; /* error: assignment of read-only variable ‘a(chǎn)’ */*p = 10;printf("a = %d, *p = %d\n", a, *p);
}
2. C++中的const變量
????????a) const常量
????????const修飾的變量,稱為常變量,也稱為常量,不能被修改(即不可以直接通過變量本身修改,也不可以通過指針間接修改)。
#include <stdio.h>int main()
{const int a = 3; /* 不會給const變量分配空間,變量a存儲在符號常量表中 */int *p = &a; /* 給符號變量a取地址運算&a,開辟臨時存儲空間,變量a的數(shù)據(jù)值,將臨時存儲空間地址賦值給指針變量p */printf("a = %d, *p = %d\n", a, *p);
// a = 5; /* error: assignment of read-only variable ‘a(chǎn)’ */*p = 10; /* 修改臨時存儲空間中的數(shù)據(jù)值 */printf("a = %d, *p = %d\n", a, *p); /* a = 3, *p = 10*/
}
b) C++中const常量和#define常量區(qū)別:
共同點:
????????const修飾的常量和#define定義的符號常量都是常量,只讀不能被修改。
不同點:
????????1) 類型檢測:const修飾的常量有數(shù)據(jù)類型,在編譯過程中做類型安全檢測;而#define定義的標識符常量無類型。
????????2) 作用域:const修飾的常量有作用域,而#define定義標識符常量無作用域限制;
在C++中常量,建議使用const常量實現(xiàn)。
3.7 struct增強
????????struct是一個關(guān)鍵字,所修飾的數(shù)據(jù)類型為結(jié)構(gòu)體數(shù)據(jù)類型
1. 在C語言中結(jié)構(gòu)體成員
????????C語言中的結(jié)構(gòu)體用于對數(shù)據(jù)成員的封裝:成員可以數(shù)據(jù)成員變量和指針(數(shù)據(jù)類型指針和函數(shù)指針)成員變量。
2. 在C++中結(jié)構(gòu)體成員增強
????????a) 成員可以C語言中的數(shù)據(jù)成員和指針成員之外,還可以將函數(shù)作為成員;
????????b) 使用結(jié)構(gòu)體數(shù)據(jù)類型(定義變量和指針)的時候,可以省略struct關(guān)鍵字,實質(zhì)就是C++中的類。
????????c) 成員增加訪問權(quán)限修飾:
????????private:私有成員,只能在當前類中訪問;
????????protected:受保護成員,可以在當前類及其派生類中訪問;
????????public:公有成員,可以在任意位置訪問。
#include <stdio.h>
#if 0
struct Stu {int num;char name[32];void (*func_p)(void);
};
#else
struct Stu {
private: /* 1. 在C++中成員新增訪問權(quán)限修飾: */int num;
protected:char name[32];
public:void (*func_p)(void);/* 2. 在C++中結(jié)構(gòu)體成員可以是函數(shù) */void show(void) {printf("show()");}};
int main()
{struct Stu stu;Stu stu1; /* 3.C++中結(jié)構(gòu)體數(shù)據(jù)類型可以省略關(guān)鍵字struct */}
4 引用(reference)
????????所謂的引用,指的是對變量進行引用訪問,也稱為給變量取別名。變量和引用為同一內(nèi)存空間。
4.1 引用定義
語法:
????????數(shù)據(jù)類型 & 引用變量名稱;
????????????????數(shù)據(jù)類型:引用變量的數(shù)據(jù)類型,需要和被引用的數(shù)據(jù)變量的數(shù)據(jù)類型保持一致;
????????????????& :特殊符號,表示所定義的數(shù)據(jù)類型變量為引用數(shù)據(jù)變量;
????????注意:
????????????????1) 在定義引用變量的時候,需要對引用變量進行初始值設置;
????????????????2) 對于引用變量,只能引用一個對象,不能引用多個對象。
#include <stdio.h>int main()
{int a = 3;int b = 5;int &c = a; /* 定義引用變量c,所引用的對象為變量a,此時a所謂的存儲空間和c所訪問的存儲空間為相同內(nèi)存空間 */printf("&a = %p, &b = %p, &c = %p\n", &a, &b, &c);printf("a = %d, b = %d, c = %d\n", a, b, c); c = b; /* 賦值運算:將變量b的值賦值給變量c */printf("a = %d, b = %d, c = %d\n", a, b, c); }
4.2 數(shù)組的引用
#include <iostream>
using namespace std;typedef int ARR[5]; int main()
{int i;int arr[5] = {1,2,3,4,5}; /* 定義有5個int類型元素的一維數(shù)組并初始化 *//* 數(shù)組的引用需要整體引用:r_arr是一個引用數(shù)組類型變量,引用的數(shù)據(jù)類型變量是一個有5個int類型元素的一維數(shù)組arr */int (&r_arr)[5] = arr; /* 等價于:ARR & r_arr = arr */r_arr[3] = 333;cout << arr <<" arr: ";for (i = 0; i < 5; i++) cout << arr[i] << " ";cout << endl;cout << r_arr <<" r_arr: ";for (i = 0; i < 5; i++) cout << r_arr[i] << " ";cout << endl;
}
4.3 函數(shù)中的引用
1. 形參引用
????????在函數(shù)中,將函數(shù)的形參設置為引用類型變量,在函數(shù)調(diào)用的時候,根據(jù)所傳遞實參確定形參具體所引用對象。實質(zhì)將實參引用傳遞給形參(實參取別名為形參),在函數(shù)內(nèi)部訪問形參也就訪問實參存儲空間(通過形參修改實參變量的值)。
#include <iostream>
using namespace std;void swap(int a, int b)
{ cout << __LINE__ << ", a = " << a << ", b = " << b << endl;int tmp = a;a = b;b = tmp;cout << __LINE__ << ", a = " << a << ", b = " << b << endl;
}/* 在函數(shù)定義的時候,將形參設置為引用變量,在函數(shù)調(diào)用的時候進行引用設置,所引用對象為傳遞的實參對象 */
void Swap(int &c, int &d)
{ cout << __LINE__ << ", c = " << c << ", d = " << d << endl;int tmp = c;c = d;d = tmp;cout << __LINE__ << ", c = " << c << ", d = " << d << endl;
}int main()
{int x = 5; int y = 2;cout << __LINE__ << ", x = " << x << ", y = " << y << endl;swap(x, y);cout << __LINE__ << ", x = " << x << ", y = " << y << endl;Swap(x, y); /* 在函數(shù)調(diào)用的時候:c引用x,d引用y;在函數(shù)調(diào)用結(jié)束,返回實參修改結(jié)果 */cout << __LINE__ << ", x = " << x << ", y = " << y << endl;
}
2. 函數(shù)返回值為引用
#include <iostream>using namespace std;int & test0(void)
{static int a = 4; /* 定義static修飾的局部變量,作用域局部模塊域,生命周期為程序執(zhí)行到程序結(jié)束 */cout << "&a :" << &a << endl;return a;
}int & test1(void)
{int b = 5; /* auto局部變量,生命周期為模塊域,不能作為返回引用對象 */cout << "&b :" << &b << endl;return b;
}int main()
{int &x = test0(); /* 在函數(shù)調(diào)用返回的時候,引用 */cout << "x = " << x << endl;cout << "&x :" << &x << endl;
#if 0int &y = test1(); /* 在函數(shù)調(diào)用返回的時候,引用 */cout << "y = " << y << endl;cout << "&y :" << &y << endl;
#endif
}
4.4 指針的引用
????????所謂的指針的引用,指的是對指針變量取別名。
#include <stdio.h>int main()
{int a = 20;int b = 10;int *p = &a;int * &q = p; /* 指針的引用,指針變量p取別名為q */printf("&p = %p, &q = %p\n", &p, &q); /* p == q */printf("a = %d, b = %d, *p = %d, *q = %d\n", a, b, *p, *q); p = &b;printf("a = %d, b = %d, *p = %d, *q = %d\n", a, b, *p, *q);
}
4.5 常量的引用
#include <iostream>
using namespace std;int main()
{
// int &a = 100; /* 在定義引用變量的時候,不可以直接對常量進行引用 *//* 在定義引用變量的時候,使用const關(guān)鍵字修飾,此時稱為常引用,只能讀訪問,不能寫訪問 */const int &b = 100; /* 常引用對象可以是常量數(shù)據(jù)值 */int c = 5;const int &d = c; /* 常引用對象可以變量 */const int x = 3;const int &y = x; /* 常引用對象可以是符號常量 */
}
4.6 引用和指針的關(guān)系
1. 在C語言、C++等其它語言中都有包含指針
????????指針的優(yōu)點和必要性:
????????????????1) 指針可以有效表示數(shù)據(jù)結(jié)構(gòu);
????????????????2) 能夠動態(tài)分配內(nèi)存,實現(xiàn)內(nèi)存的自由管理;
????????????????3) 能夠方便的使用字符串,便捷高效地使用數(shù)組;
????? ? ? ? ? ? ?4) 指針直接域數(shù)據(jù)的存儲地址有關(guān)。
2. 引用和指針的區(qū)別
????????指針式變量的地址,引用是給變量取別名(引用本質(zhì)是通過指針實現(xiàn))。
????????????????1) 程序為指針變量分配內(nèi)存空間,而不為引用分配。
????????????????2) 指針使用地址解引用訪問運算符(*)解引用訪問所指向空間數(shù)據(jù),而引用指針訪問。
????????????????3) 指針在定義的時候,可以不設置指向,后續(xù)過程中設置,同時指向可以改變;而引用在定義的時候需要設置引用對象,且設置后不能改變引用對象;
????????????????4) 指針中有空指針NULL,而引用中沒有空引用;引用的訪問效率更高。
????????????????5) sizeof計算指針和引用空間大小,指針固定大小;而引用和引用對象數(shù)據(jù)類型有關(guān);
????????????????6) 指針可以是多級指針沒有限制,而引用只能是一級引用;
????????????????7) 自加(++)自減(--)運算,指針實現(xiàn)指向的偏移,引用實現(xiàn)引用對象數(shù)據(jù)結(jié)果的改變。
三, 函數(shù)重載和函數(shù)默認參數(shù)
1 函數(shù)重載
????????所謂的函數(shù)的重載,指的是在相同作用域下的多個函數(shù)名相同其參數(shù)不同的多個函數(shù)稱為重載函數(shù),整個行為稱為函數(shù)重載。
????????重載函數(shù)具備的條件:
????????????????1) 作用域相同;
????????????????2) 函數(shù)名稱相同;
????????????????3) 參數(shù)不同:
????????????????????????參數(shù)的數(shù)據(jù)類型不同、參數(shù)個數(shù)不同、參數(shù)順序不同;
#include <stdio.h>
/* 重載函數(shù):包含了4個 */
int add(int a, int b)
{return a+b;
}float add(float a, float b)
{return a+b;
}double add(double a, double b)
{return a+b;
}int add(int a, int b, int c)
{return a+b+c;
}
int main()
{/* 對于重載函數(shù)的訪問:在程序編譯過程中,根據(jù)所傳遞參數(shù)的數(shù)據(jù)類型決定所調(diào)用的函數(shù) */printf("%d\n", add(5, 6)); printf("%f\n", add(5.1, 6.3));printf("%d\n", add(4, 5, 6));}
注意:
1. C++中,函數(shù)重載是由編譯器決定,
????????C語言使用的是gcc編譯器,不支持函數(shù)重載;其實質(zhì)在編譯(語法檢測并生成匯編代碼)過程中,C語言函數(shù)的編譯為匯編指令的過程中,直接使用函數(shù)名作為代碼起始符號。
????????C++使用的是g++編譯,支持函數(shù)重載;其實質(zhì)在編譯(語法檢測并生成匯編代碼)過程中,C++語言函數(shù)的編譯為匯編指令的過程中,將函數(shù)名及其形參數(shù)據(jù)類型符號中的起始字母作為代碼起始符。
????????2. 在函數(shù)的重載中,只與函數(shù)的形參有關(guān),和函數(shù)的返回值無關(guān)。
????????3. 重載函數(shù)的調(diào)用,在程序編譯過程中根據(jù)所傳遞參數(shù)的數(shù)據(jù)類型決定所調(diào)用的重載函數(shù)。
2 函數(shù)的默認參數(shù)值
????????所謂的函數(shù)默認參數(shù)值,指的是在函數(shù)聲明過程中,給形參設置默認數(shù)據(jù)值;在函數(shù)調(diào)用的時候,如果有給形參傳遞實參值,則形參使用的是傳遞的實參數(shù)據(jù)值,如果沒有給形參傳遞實參值,則形參使用所設置的默認參數(shù)值。
注意:
????????1. 函數(shù)默認參數(shù)值的設置,是在函數(shù)聲明的時候進行設置。
????????2. 在設置默認參數(shù)值過程中,其中某一個參數(shù)設置了默認參數(shù)值,其該參數(shù)右邊的所以參數(shù)均要設置默認參數(shù)值。
????????3. 設置默認參數(shù)值的函數(shù)使用:
????????????????1) (參數(shù)個數(shù) - 已設置默認參數(shù)值個數(shù)) <= 所傳遞參數(shù)值個數(shù) <= 參數(shù)個數(shù)
????????????????2) 所傳遞的實參從左向右依次順序傳遞給形參。
#include <stdio.h>void PrintVal(int a = 0, int b = 0, int c = 0)
{printf("a = %d, b = %d, c = %d\n", a, b, c);
}void print_val(int x, int y = 10, int z = 10);int main()
{PrintVal(3,4,5); /* 函數(shù)調(diào)用傳遞實參,形參使用傳遞的參數(shù)值 */PrintVal(); /* 函數(shù)調(diào)用未傳遞實參,形參使用默認參數(shù)值 */print_val(1, 2, 3); /* 所傳遞的實參從左向右依次順序賦值給形參x,y,z */print_val(1, 2); print_val(1);
}void print_val(int x, int y, int z)
{printf("x = %d, y = %d, z = %d\n", x, y, z);
}
3 函數(shù)的占位參數(shù)
????????所謂的函數(shù)的占位參數(shù),指的是函數(shù)定義的時候,函數(shù)的形參只有數(shù)據(jù)類型而沒有形參變量名,此時的參數(shù)稱為占位參數(shù)。
????????其占位參數(shù)值具備占位的意義,而不具備其它意義。主要用于在運算符重載過程中實現(xiàn)對于運算符++/--的前后運算之分。
????????占位參數(shù)可以設置默認參數(shù)值。
/* 在函數(shù)定義的時候,給函數(shù)設置占位參數(shù),同時給占位參數(shù)設置默認參數(shù)值 */
void func(int a, int = 3)
{printf("a = %d\n", a);
}
void func(int, double x)
{printf("x = %f\n", x);
}int main()
{func(1, 4); func(4);func(2, 3.4);
}
4 函數(shù)重載和函數(shù)默認參數(shù)值同時使用
四, 內(nèi)聯(lián)函數(shù)
1 內(nèi)聯(lián)函數(shù)的定義
所謂的內(nèi)聯(lián)函數(shù),類似于C語言中的預定義宏函數(shù)。具體的定義實現(xiàn):
1) 非成員函數(shù)定義為內(nèi)聯(lián)函數(shù)
????????函數(shù)的聲明和函數(shù)的定義為整體實現(xiàn)。并且在函數(shù)前使用關(guān)鍵字inline修飾。
/* 函數(shù)聲明和定義為整體表示,且使用關(guān)鍵字inline進行修飾的函數(shù)稱為內(nèi)聯(lián)函數(shù) */
inline int func(int a)
{return a++;
}
2) 成員函數(shù)定義為內(nèi)聯(lián)函數(shù)
????????一般表示類成員函數(shù),如果定義為內(nèi)聯(lián)函數(shù)需要在類的內(nèi)部完成成員函數(shù)的聲明和定義。關(guān)鍵字inline可以省略也可以保留。
class Demo {/* 類內(nèi)部實現(xiàn)成員函數(shù)的定義和聲明,關(guān)鍵inline可以省略,此時的成員函數(shù)自動為內(nèi)聯(lián)函數(shù) */int func(int a){return a++; }
}
2 內(nèi)聯(lián)函數(shù)編譯
????????對于一個內(nèi)聯(lián)函數(shù),并不是完全由關(guān)鍵字inline和成員函數(shù)所定義的位置決定,同時會由編譯器共同決定。
????????內(nèi)聯(lián)是設計者給編譯器的建議,只有滿足編譯內(nèi)聯(lián)規(guī)則的時候,才會將其生成為內(nèi)聯(lián)函數(shù)。同時編譯器也會自動將未聲明為內(nèi)聯(lián)的函數(shù)生成為內(nèi)聯(lián)函數(shù)
????????c++內(nèi)聯(lián)編譯會有一些限制:
????????1) 不能存在任何形式的循環(huán)語句;
????????2) 不能存在過多的條件判斷語句
????????3) 函數(shù)體不能過于龐大
????????4) 不能對函數(shù)進行取址操作
3 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別
內(nèi)聯(lián)函數(shù)相當于普通函數(shù)而言:
????????1) 占用更多的代碼存儲空間:
????????????????內(nèi)聯(lián)函數(shù)在編譯過程中做函數(shù)代碼的替換;
????????2) 執(zhí)行效率更高
????????????????內(nèi)聯(lián)函數(shù)的優(yōu)勢省去函數(shù)調(diào)用時的壓棧、跳轉(zhuǎn)以及返回開銷等,執(zhí)行效率更高。
????????????????內(nèi)聯(lián)函數(shù)以空間換時間。
五, C++中的輸入輸出
1. 繼承了C語言中的輸入輸出
????????直接使用C語言中標準C庫所提供大的輸入輸出函數(shù):printf、scanf、getchar、putchar等函數(shù)實現(xiàn)數(shù)據(jù)的輸入和輸出功能;
2. C++中新增了標準輸入輸出
????????a) 標準輸出流(std::cout)
????????std::cout 作為標準輸出流;
????????使用格式:
????????????????std::cout << 數(shù)據(jù)/* << 重定向訪問運算符,將數(shù)據(jù)重定向到標準輸出流中 */
注意:
1) 在有多個數(shù)據(jù)需要輸出的時候,可以使用多個重定向訪問運算符<<進行輸出鏈接;
2) 數(shù)據(jù)可以是變量、常量;
3) std::endl 作為標準輸出流的換行符,等價于C語言中"\n";
#include <iostream>using namespace std;int main()
{int a = 3;float b = 5.1;char *str = "hello ikun";int arr[5] = {1,2,3,4,5};/* 有多個數(shù)據(jù)需要輸出,則使用重定向訪問運算符<<進行數(shù)據(jù)的鏈接輸出 */std::cout << "a = " << a << ", b = " << b << std::endl;cout << "&a = " << &a << endl;/* 輸出變量為char指針變量(或者指針常量-實在就是字符串)的時候,輸出的是指針所指向字符串數(shù)據(jù)* 指針變量需要輸出的是指針的地址值,可以將其轉(zhuǎn)換為void類型指針輸出*/cout << str << endl; /* 輸出字符串數(shù)據(jù),在遇到'\0'結(jié)束 */cout << (void *)str << endl; /* 輸出指針地址值 *//* 需要輸出的數(shù)組變量名,此時表示的是數(shù)組首元素地址:數(shù)組不能整體訪問 */cout << arr << endl;
}
b) 標準輸入流(std::cin)
std::cin >> 數(shù)據(jù)變量名稱/* 從標準輸入流中讀取數(shù)據(jù)賦值給變量 */
????????注意:如果需要輸入的數(shù)據(jù)變量有多個,可以使用多個重定向訪問運算符>>鏈接實現(xiàn)。
#include <iostream>using namespace std;int main()
{int a = 3;float b = 5.1;char str[] = "hello ikun";std::cin >> a; /* 從標準輸入流讀取數(shù)據(jù)賦值給變量a */std::cin >> b; /* 從標準輸入流讀取數(shù)據(jù)賦值給變量b */std::cout << "a = " << a << ", b = " << b << std::endl;std::cin >> a >> b; /* 從標準輸入流讀取數(shù)據(jù)賦值給變量a和變量b */std::cout << "a = " << a << ", b = " << b << std::endl;std::cin >> str;cout << str;
六,字符串類
????????在C++中字符串表示:
1. 繼承C語言中字符串的特征
????????實質(zhì)使用字符數(shù)組空間實現(xiàn)字符串數(shù)據(jù)的存儲,以字符'\0'作為結(jié)束標識。
2. 在C++標準類庫中新增string字符串類
????????可以實現(xiàn)是字符串數(shù)據(jù)的存儲和運算,string類表示:
????????std::string 是標準C++類庫中所提供的字符串數(shù)據(jù)類型;內(nèi)部不僅實現(xiàn)了字符串數(shù)據(jù)的存儲;
????????????????1) 提供了字符串數(shù)據(jù)運算符重載功能,直接實現(xiàn)基本運算實現(xiàn)字符串數(shù)據(jù)的運算。
????????????????+:實現(xiàn)兩個字符串數(shù)據(jù)的連接;
????????????????=:實現(xiàn)字符串賦值運算,等價于C語言中函數(shù)strcpy功能;
????????????????+=:在原字符串數(shù)據(jù)后追加新字符串數(shù)據(jù),等價于C語言中函數(shù)strcat功能;
????????????????比較運算符:>、>=、<、<=、==、!=
????????????????[]:數(shù)組元素訪問運算符,訪問字符串中指定下標元素,可以讀寫訪問。
????????2) 提供其它訪問接口
????????????????size():計算字符串中字符個數(shù);
????????????????c_str():將C++的字符串數(shù)據(jù)轉(zhuǎn)換為C語言指針形式表示;
七, C++內(nèi)存管理
1 C語言中存管理方式
1. 靜態(tài)分配:
????????全局變量:
????????????????存儲靜態(tài)存儲區(qū)
????????????????生命周期是程序執(zhí)行到程序結(jié)束
????????????????作用域(或者連接屬性):未被static修飾的全局變量,其作用域為程序域;被static修飾的全局變量其作用域為文件域。
????????局部變量:
????????存儲位置:未被static修飾的局部變量存儲在棧區(qū)、被static修飾的局部變量存儲在靜態(tài)存儲區(qū);
????????生命周期:未被staitc修飾的局部變量生命周期為語句執(zhí)行到模塊結(jié)束;被static修飾的局部變量生命周期為語句執(zhí)行到程序結(jié)束。
????????作用域:為局部作用域。
????????常量:存儲在數(shù)據(jù)常量區(qū)
2. 動態(tài)分配
????????使用動態(tài)內(nèi)存分配函數(shù)(malloc、calloc、realloc)按照使用者指定空間大小動態(tài)分配內(nèi)存,同時在內(nèi)存使用結(jié)束的時候使用函數(shù)(free)進行動態(tài)釋放。
????????存儲位置:堆區(qū)
????????生命周期:由使用者跟進實際需求動態(tài)分配和釋放決定;
#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
2 C++內(nèi)存管理
1. C++繼承C語言所有內(nèi)存管理方式
2. 同時引入新的內(nèi)存管理方式
????????在動態(tài)內(nèi)存管理的基礎上,新增使用運算符new和delete動態(tài)管理內(nèi)存方式
2.1 運算符new和delete的使用
1. 運算符new動態(tài)分配內(nèi)存空間
????????動態(tài)開辟單個數(shù)據(jù)元素存儲空間,實質(zhì)就是分配數(shù)據(jù)類型變量存儲空間:
????????數(shù)據(jù)類型 * 指針變量名 = new 數(shù)據(jù)類型;
????????動態(tài)開辟連續(xù)多個相同數(shù)據(jù)類型元素存儲空間,實質(zhì)就是分配數(shù)組元素存儲空間:
????????數(shù)據(jù)類型 指針變量名 = new 數(shù)據(jù)類型[常量表達式];/ 常量表達式表示所分配數(shù)組元素的個數(shù) */
2. 運算符delete動態(tài)釋放內(nèi)存空間
????????單個數(shù)據(jù)元素空間的釋放
????????????????delete 指針變量名;
????????連續(xù)多個數(shù)據(jù)元素存儲空間的釋放
????????????????delete []指針變量名;
#include <iostream>using namespace std;int main()
{int *p = new int; /* 開辟1個int數(shù)據(jù)類型元素存儲空間 */*p = 5;std::cout << *p << std::endl;delete p; /* 釋放p指向存儲空間 */p = NULL;int *q = new int [5]; /* 開辟連續(xù)存儲空間:可以存儲5個int類型數(shù)據(jù)元素 */for (int i = 0; i < 5; i++)*(q+i) = i;for (int i = 0; i < 5; i++)cout << "q[" << i<<"] = " << q[i] << endl;delete []q; /* 釋放q指向連續(xù)存儲空間 */
}
2.2 new和malloc區(qū)別
????????在C++中,new和malloc用于動態(tài)內(nèi)存管理
1. 屬性不同
????????new和delete,是C++中的運算符關(guān)鍵字,由編譯器所支持;
????????????????運算符new和delete可以重載;
????????malloc和free,是庫函數(shù),在使用的時候需要添加頭文件和庫支持。
????????????????無法對其進行重載
2. 使用方式不同
????????malloc在動態(tài)開辟空間的時候需要顯示填入所申請內(nèi)存空間的大小;
????????new在動態(tài)開辟空間的時候不需要顯示填入內(nèi)存空間的大小,會根據(jù)new的數(shù)據(jù)類型自動分配;
int *malloc_p = (int *)malloc(4);
free(malloc_p));
int *new_p = new int;
delete new_p;
3. 存儲內(nèi)存位置不同
????????malloc所申請的內(nèi)存一定是堆區(qū)存儲空間;
????????new所申請的內(nèi)存空間為自由存儲空間;
????????C++內(nèi)存區(qū)間分為:堆區(qū)、棧區(qū)、自由存儲區(qū)、全局靜態(tài)存儲區(qū)、常量存儲區(qū)
????????????????自由存儲區(qū)是C++中動態(tài)內(nèi)存分配和釋放對象的一個概念,通過new分配的內(nèi)存區(qū)域稱為自由存儲區(qū),需要通過delete釋放內(nèi)存;自由存儲區(qū)可以是堆區(qū)、棧區(qū)、全局靜態(tài)存儲區(qū),主要是由new的實現(xiàn)和C++編譯器默認new申請內(nèi)存決定,大多數(shù)情況下new默認使用堆區(qū)實現(xiàn)自由存儲區(qū)。
4. 返回類型不同
????????malloc返回值為void類型指針,需要根據(jù)使用進行類型強制轉(zhuǎn)換;
????????new返回值為所分配數(shù)據(jù)類型指針,無需強制轉(zhuǎn)換直接使用。
5. 分配失敗情況不同
????????malloc失敗返回NULL,可以判斷使用;
????????new失敗會拋出bac_alloc異常;
6. 內(nèi)存大小擴張
????????malloc可以使用realloc擴張所分配的內(nèi)存;
????????new沒有擴張內(nèi)存機制。
7. 定義對象系統(tǒng)調(diào)度過程不同
????使用new操作符來分配對象內(nèi)存時會經(jīng)歷三個步驟:
????????a) 調(diào)用operator new 函數(shù)(對于數(shù)組是operator new[])分配一塊足夠的內(nèi)存空間(通常底層默認使用malloc實現(xiàn),除非程序員重載new符號)以便存儲特定類型的對象;
????????b) 編譯器運行相應的構(gòu)造函數(shù)以構(gòu)造對象,并為其傳入初值。
????????c) 對象構(gòu)造完成后,返回一個指向該對象的指針。
使用delete操作符來釋放對象內(nèi)存時會經(jīng)歷兩個步驟:
????????d) 調(diào)用對象的析構(gòu)函數(shù)。
????????e) 編譯器調(diào)用operator delete(或operator delete[])函數(shù)釋放內(nèi)存空間(通常底層默認使用free實現(xiàn),除非程序員重載delete符號)。