45
46 常量指針必須初始化
47 一條語句可以定義出不同類型的變量 int i=10, *p=&i,&r =i;
48 應(yīng)該是intp 而不是intp
49 **表示指向指針的指針 p52
50 指針是對(duì)象,所以存在對(duì)于指針的引用
int *p;
int *&r=p;
51 在默認(rèn)狀態(tài)下 ,const對(duì)象只是在文件內(nèi)部有效
52 只在一個(gè)文件中定義const 而在其他多個(gè)文件中聲明并使用它:
唯一的解決辦法是 對(duì)于const變量不管是聲明還是定義都添加 extern 關(guān)鍵字,這樣只需要定義一次就夠了
file_1.cc定義并初始化一個(gè)常量: extern const int bufsize = fcn();
file_1.h頭文件:extern const int buffSize ;//與file_1.cc中定義的buffSize是同一個(gè)
53 const 的引用 (對(duì)常量的引用) 不能修改他所綁定的對(duì)象
const int ci=1024;
const int &r1=ci;
54 常量可以引用常量和非常量,非常量只能引用非常量
55 初始化常量引用時(shí)允許用任意的表達(dá)式作為初始值 p55
56 double dval =3.14;
const int &ri=dval;
這里編譯器創(chuàng)建了一個(gè)臨時(shí)量對(duì)象
const int temp=dval; //由雙精度浮點(diǎn)數(shù)生成一個(gè)臨時(shí)的整型常量
const int &ri=temp; //讓ri綁定這個(gè)臨時(shí)常量
而非常量無法跨類引用!!
57 int i=42;
const int &r2 =i; //r2綁定對(duì)象i,但是不允許通過r2修改i的值
(常量引用非常量)
58 允許令一個(gè)指向常量的指針指向非常量
double dval =3.14;
const double *cptr =&dval;(指向常量的指針不能通過cptr改變對(duì)象的值)
59 const(指向常量對(duì)象) double *const(常量指針) pip =& pi(z指向常量對(duì)象的常量指針) p56
60 頂層const:指針本身是個(gè)常量 (不允許改變指針pi的值(地址))
底層const:指針?biāo)赶虻膶?duì)象是個(gè)常量 (允許改變指針pi的值(地址))
聲明引用&的const都是底層const (所引用的對(duì)象是個(gè)常量)
const int ci =42; 頂層const (不允許改變ci的值)
61 考入和考出的對(duì)象必須擁有相同的底層const資格,或者兩個(gè)對(duì)象的數(shù)據(jù)類型必須能夠轉(zhuǎn)換,一般來說,非常量可以轉(zhuǎn)換為常量
62 常量拷貝給非常量是可以的,但是不能非常量引用常量
63 指向常量的指針可以指向指向非常量的指針,但是反過來不行
64
65 允許將變量聲明為constexpr 類型以便由編譯器來驗(yàn)證變量的值是否是一個(gè)常量表達(dá)式,聲明為constexpr的值一定是一個(gè)常量,而且必須由常量表達(dá)式初始化 (C++11特性)
66 字面值類型: 算數(shù)類型,引用,指針
67 定義于函數(shù)體內(nèi)的變量沒有固定地址,不能使用constexpr ;而函數(shù)體外部的對(duì)象定義時(shí)的地址固定不變,可以使用constexpr
68
如果constexpr聲明中如果定義了一個(gè)指針,那么constexpr只對(duì)指針有效,對(duì)于其所指向的對(duì)象無關(guān)
constexpr int * q =nullptr 相等于 int const * q 表示q是一個(gè)指向整數(shù)的常量指針(頂層const)
constexpr const int *p= &i; 頂層 底層
69 類型別名 typedef /using 變量別名是&
typedef double wages; //wages 是double的一個(gè)別名
typedef wages base , *p; //base是 double的另一個(gè)別名 p是double *的別名
using SI= int; //SI是int 的別名
這里注意 typedef char * pstring ;
const pstring cstr=0; cstr是指向char的常量指針
上面這句話不等于 const char * cstr =0; p61
這種理解是錯(cuò)誤的 ,用到了pstring 其基本數(shù)據(jù)類型是指針, 而用char *重寫過后,數(shù)據(jù)類型就變成了char ,*成為了聲明符的一部分
70 讓編譯器分析表達(dá)式類型 auto (C++11 新特性)
使用auto 時(shí)一條語句只能有一個(gè)基本數(shù)據(jù)類型
auto i = 0 , *p=&i; //i為整數(shù),p為整型指針
71 使用引用其實(shí)是在使用引用的對(duì)象,當(dāng)引用參與初始化時(shí),真正參與初始化的是引用對(duì)象的值
72 auto一般會(huì)忽略頂層const 而底層const 會(huì)被保留下來
73 auto 對(duì)常量對(duì)象取地址是一種底層const
74 不能為非常量引用綁定字面值,可以為常量引用綁定字面值
75 設(shè)置一個(gè)類型為 auto的引用時(shí),初始值中的頂層常量屬性任然保留。和往常一樣,如果我們給初始值綁定一個(gè)引用,則此時(shí)的常量就不是頂層常量了。
76
77 使用decltype返回類型(c++11特性) 如果decltype使用的表達(dá)式是一個(gè)變量,那么decltype返回該變量的類型(包括頂層const以及引用在內(nèi))
p63
decltype(cj) x=0;
78 decltype?的結(jié)果是引用類型,如果想讓結(jié)果是r所指的類型,那么可以把r作為表達(dá)式的一部分,如r+0,顯然這個(gè)表達(dá)式的結(jié)果是一個(gè)具體值而不是引用
如果是解引用操作,那么decltype將得到引用類型 因此,decltype(*p)的結(jié)果類型是int &而不是int
79 decltype((variable))雙層括號(hào)的結(jié)果永遠(yuǎn)是引用,而 devcltype(variable)的結(jié)果只有當(dāng)變量本身就是一個(gè)引用的時(shí)候才是引用
80 類體后面可以緊跟變量名以示對(duì)該類型對(duì)象的定義,所以分號(hào)不能少
81 對(duì)象的定義 和類的定義 最好不要放在一起
82
83 2.41 習(xí)題復(fù)習(xí)
#include#includeusing namespace std;
class Sales_data {friend std:: istream & operator >>(std::istream& , Sales_data&);
friend std:: ostream& operator<<(std::ostream&, const Sales_data&);
friend bool operator<(const Sales_data&, const Sales_data&);
friend bool operator==(const Sales_data&, const Sales_data&);
public:
Sales_data() = default;
Sales_data(const std::string& book) :bookNo(book) {}
Sales_data(std::istream& is) {is >>*this; }
public:
Sales_data& operator +=(const Sales_data&);
std::string isbn() const {return bookNo; }
private:
std::string bookNo;
unsigned units_sold = 0;
double sellingprice = 0;
double saleprice = 0.0;
double discount = 0.0;
};
inline bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{return lhs.isbn() == rhs.isbn();
}
Sales_data operator +(const Sales_data&, const Sales_data&);
inline bool operator == (const Sales_data& lhs, const Sales_data& rhs)
{return lhs.units_sold == rhs.units_sold && lhs.sellingprice == rhs.sellingprice && lhs.saleprice == rhs.saleprice && lhs.isbn() == rhs.isbn();
}
inline bool operator !=(const Sales_data& lhs, const Sales_data& rhs)
{return !(lhs == rhs);
}
Sales_data& Sales_data::operator+=(const Sales_data& rhs)
{units_sold += rhs.units_sold;
saleprice = (rhs.saleprice * rhs.units_sold + saleprice * units_sold) / (rhs.units_sold + units_sold);
if (sellingprice != 0)
{discount = saleprice / sellingprice;
return *this;
}
}
Sales_data operator +(const Sales_data& lhs, const Sales_data& rhs)
{Sales_data ret(lhs);
ret += rhs;
return ret;
}
std::istream& operator>>(std::istream& in, Sales_data& s)
{in >>s.bookNo >>s.units_sold >>s.sellingprice >>s.saleprice;
if (in && s.sellingprice != 0)
{s.discount = s.saleprice / s.sellingprice;
}
else
{s = Sales_data();
}
return in;
}
std:: ostream& operator<<(std::ostream& out, const Sales_data& s)
{out<< s.isbn()<< " "<< s.units_sold<< " "<< s.sellingprice<< " "<< s.saleprice<< " "<< s.discount;
return out;
}
int main()
{Sales_data book;
cout<< "請(qǐng)輸入銷售記錄"<< endl;
while (cin >>book) {cout<< "ISBN,售出本書,原始價(jià)格,實(shí)售價(jià)格,折扣為"<< book<< endl;
}
Sales_data trans1, trans2;
cout<< "請(qǐng)輸入兩條ISBN相同的銷售記錄"<< endl;
cin >>trans1 >>trans2;
if (compareIsbn(trans1, trans2))
{cout<< "匯總信息:ISBN,售出本書,原始價(jià)格,實(shí)售價(jià)格,折扣為"<< trans1 + trans2<< endl;
}
else
{cout<< "兩條銷售記錄的ISBN不同"<< endl;
}
Sales_data total, trans;
cout<< "請(qǐng)輸入幾條ISBN相同的銷售記錄"<< endl;
if (cin >>total) {while (cin >>trans)
{ if (compareIsbn(total, trans))
total = total + trans;
else
cout<< "當(dāng)前書籍ISBN不同"<< endl;
break;
}
cout<< "有效匯總信息:ISBN,售出本數(shù),原始價(jià)格,實(shí)售價(jià)格,折扣為"<< total<< endl;
}
else
{std::cout<< "沒有數(shù)據(jù)"<< endl;
return -1;
}
int num = 1;
cout<< "請(qǐng)輸入若干銷售記錄:"<< endl;
if (cin >>trans1) {while (cin >>trans2)
{ if (compareIsbn(trans1, trans2))
num++;
else
{ cout<< trans1.isbn()<< "共有"<< num<< "條銷售記錄"<< endl;
trans1 = trans2;
num = 1;
}
cout<< trans1.isbn()<< "共有"<< num<< "條銷售記錄"<< endl;
}
}
else
{cout<< "沒有數(shù)據(jù)"<< endl;
return -1;
}
return 0;
}
84 確保頭文件多次包含還是能安全工作的常用技術(shù)是預(yù)處理器
預(yù)處理功能(頭文件保護(hù)符)
#ifdef 當(dāng)且僅當(dāng)變量已定義為真
#ifndef 當(dāng)且僅當(dāng)變量未定義為真,一旦檢查結(jié)果為真,則執(zhí)行后續(xù)操作指導(dǎo)遇到#endif指令為止
85
如果后面再包含sales_data.h 那么#ifndef的檢查結(jié)果為假,那么編譯器將會(huì)忽略#ifndef到#endif 之間的部分
86 基于頭文件中類的名字構(gòu)建保護(hù)符的名字,以確保其唯一性,一般把預(yù)處理變量的名字全部大寫
87 頭文件即使還沒有包含在任何其他頭文件中,也應(yīng)該設(shè)置保護(hù)符
88 const 對(duì)象一旦定義就無法再賦新值,所以必須初始化
89 #ifndef #define #endif
90 兩種重要的標(biāo)準(zhǔn)庫類型:string vector
91 用using 聲明不需要后面專門使用前綴
using namespace::name;
每一個(gè)名字都需要單獨(dú)的聲明
92 頭文件不應(yīng)該包含using 聲明,如果這樣,每個(gè)使用該頭文件的文件都會(huì)有這個(gè)聲明,會(huì)產(chǎn)生一些不必要的名字沖突
93 六種初始化string 的方式
94 拷貝初始化和直接初始化:沒有等號(hào)的是直接初始化
95 string的操作 p77
96 cin>>s //將string對(duì)象讀入s,遇到空白停止
97 string 連續(xù)輸入輸出
98 使用getline函數(shù)讀一行數(shù),直到遇到換行符為止,
99 size_type是size函數(shù)返回的類型 100 如果一條表達(dá)式中已經(jīng)有了size()函數(shù)就不要使用int 了,這樣可以避免混用int 和 unsigned 可能帶來的問題 103 string的輸入運(yùn)算符自動(dòng)忽略開頭的空白,從第一個(gè)真正的字符開始讀起,知道遇到下一處空白為止 104 cctype頭文件 #include 函數(shù)和定義 p82 107 vector 是一個(gè)類模板 而 非類型 108 vector 初始化 對(duì)象 p88 110 vector對(duì)象的高效增長 先定義一個(gè)空的vector對(duì)象,再在運(yùn)行時(shí)向其中添加具體值(動(dòng)態(tài)添加元素) 111 vector操作 p91 112 vector ::size_type 正確(必須指定它是由哪種類型定義的) 115 遍歷vector對(duì)象不同元素的每個(gè)字符 116 練習(xí)3.20 119 如果兩個(gè)迭代器指向的元素都是同一個(gè)容器的尾后迭代器,那么他們相等;否則不等 123 cbegin cend 是c++11新特性為了得到const_iterator類型的返回值(無論vector是否是常量) 126 迭代器運(yùn)算 p99-100 127 二分搜索法 p100 你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
s.size()
101 字符串之間比大小,先是比長度再是比第一對(duì)相異字符
102 當(dāng)字符字面值和字符串字面值相加時(shí),必須保證加號(hào)兩邊的運(yùn)算對(duì)象其中一個(gè)是string類型(字符串字面值不是string對(duì)象)
getline從輸入流中讀取數(shù)據(jù),知道遇到換行符位置,換行符也被讀進(jìn)去,但是不會(huì)儲(chǔ)存在最后的字符串中
105 基于范圍的for語句
想要改變對(duì)象中的字符值,必須把循環(huán)變量定義成引用類型
106 使用下標(biāo)時(shí),將下標(biāo)的類型設(shè)為string::size_type 這個(gè)是個(gè)無符號(hào)數(shù),所以不會(huì)小于0,只要讓其小于size()就可以了
vector
其中每個(gè)元素都是vector的對(duì)象
109 push_back函數(shù) p90
運(yùn)用push_back給vector對(duì)象添加新元素
113 不是所有的vector對(duì)象都能互相比較
114 vector對(duì)象不能直接通過下表添加元素,必須使用push_back,下標(biāo)運(yùn)算只能用于訪問已經(jīng)存在的元素,而不能用來添加元素
117 string 和 vector都支持迭代器(除了下標(biāo)運(yùn)算可以訪問string對(duì)象的字符或vector對(duì)象的元素,也可以使用迭代器)
118 begin是負(fù)責(zé)返回指向第一個(gè)元素的迭代器
end是負(fù)責(zé)范圍指向容器尾部元素的下一個(gè)位置(尾后迭代器)
如果容器為空begin和end同時(shí)返回同一個(gè)迭代器,都是尾后迭代器
120 標(biāo)準(zhǔn)容器迭代器的運(yùn)算符 p96
121 可以通過解引用迭代器來獲得它所指示的元素
122 const_iterator iterator 是可以表示迭代器的類型,兩者區(qū)別是后者可讀可寫,前者不可寫(每個(gè)容器類定義了一個(gè)名為iterator的類型,該類型支持迭代器概念所規(guī)定的一套操作)
124 (*it).empty() 解引用調(diào)用迭代器所指向類的成員函數(shù) it->empty()也行
125 不能在范圍for循環(huán)中向vector對(duì)象添加元素,改變vector容量的操作會(huì)使得vector對(duì)象的迭代器失效
凡是使用迭代器的循環(huán)體,都不要像迭代器所屬的容器添加元素!
difference_type是帶符號(hào)整型數(shù),是兩個(gè)迭代器距離的返回類型
當(dāng)前文章:C++PrimerPlus第五版筆記(p51-100)-創(chuàng)新互聯(lián)
網(wǎng)頁URL:http://weahome.cn/article/ppoic.html