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