- 初始化與賦值
初始化的含義是創(chuàng)建變量的時候賦予其一個初始值遍搞,賦值的含義是把對象的當前值擦除,而以一個新值來替代盗迟。
列表初始化:int units = 0; int units = {0}; int units{0}; int units(0);
但是如果初始值存在丟失信息的風險劫侧,編譯器將報錯。
定義在函數(shù)體內(nèi)部的內(nèi)置類型變量將不被初始化葵礼。未被初始化的內(nèi)置類型變量的值是未定義的,如果拷貝或者訪問該值將引發(fā)錯誤并鸵。類的對象如果沒有顯式地初始化鸳粉,則其值由類確定。 - 分離式編譯
將聲明和定義區(qū)分開來园担,聲明使得名字為程序所知届谈,文件如果想使用別處定義的名字則必須包含對那個名字的聲明。定義負責創(chuàng)建與名字關(guān)聯(lián)的實體弯汰,申請存儲空間艰山,也可能會為變量賦一個初始值。
extern 聲明一個變量而不是定義它咏闪。
任何包含了顯式初始化的聲明即成為定義曙搬。
變量能且只能被定義一次,但是可以被多次聲明鸽嫂。
定義在函數(shù)體外的標識符不能以下劃線開頭纵装。 - 作用域
std::cout << ::reused
顯示的訪問全局變量,因為全局作用域沒有名字据某,所以當作用域操作符左側(cè)為空橡娄,向全局作用域發(fā)出請求。 - 復合類型
- 引用
引用為對象起了另外一個名字癣籽,引用類型引用另外一種類型挽唉,通過聲明符寫成&d的形式來定義引用類型。int &refVal = ival; //refVal指向ival
定義引用的時候筷狼,程序把引用和它的初始值綁定在一起橱夭,一旦初始化完成,引用將和它的初始值對象一直綁定在一起桑逝,所以引用必須初始化。
引用本身不是一個對象俏让,所以不能定義引用的引用楞遏。引用只能綁定在對象上茬暇,不能與字面值或某個表達式的計算結(jié)果綁定。 - 指針
指針也實現(xiàn)了對其它對象的間接訪問寡喝,指針本身就是一個對象糙俗,允許對指針賦值和拷貝。int *d;//定義指針
预鬓。
指針存放某個對象的地址巧骚,獲取該地址,使用取地址符格二,int *p = &ival;
劈彪,引用不是對象,沒有實際地址顶猜,所以不能定義指向引用的指針沧奴。
其它所有指針類型都要與它所指向的對象嚴格匹配。
如果指針指向了一個對象长窄,允許使用解引用符*來訪問對象滔吠。int val = 42; int *p = &val; cout << *p;
,如果給解引用的結(jié)果賦值挠日,實際上就是給指針所指的對象賦值疮绷。
空指針int *p1 = nullptr;
得到空指針最直接的方法是用nullptr來初始化指針∠保或者將指針初始化為0冬骚,但是不能賦給int變量的0,int *p2 = 0;
或者是實用cstdlib中的預處理變量NULL賦值郑原,#include cstdlib int *p3 = NULL;
預處理器是運行與編譯過程之前的一段程序唉韭,預處理變量不屬于命名空間std,由預處理器負責管理犯犁,所以不需要加上std::属愤,最好使用nullptr
指針最好初始化,定義了對象之后再定義指向它的指針∷嵋郏或者先初始化為nullptr
賦值永遠改變的是等號左側(cè)的對象住诸,pi改變是指針,*pi改變的是指針指向的對象涣澡。
void*指針贱呐,可以用于存放任意對象的地址,double obj = 3.14; void *pv = &obj;
入桂,但是不能直接操作void*指針所指的對象奄薇,因為并不知道對象是什么類型,因此無法再這個對象上操作抗愁。
void*來看內(nèi)存空間就是內(nèi)存空間馁蒂,沒辦法訪問內(nèi)存空間中存儲的對象呵晚。
類型修飾符如*,&只是聲明符的一部分,變量的定義包括基本數(shù)據(jù)類型和一組聲明符沫屡。 所以要定義多個指針變量必須這樣int \*p1, \*p2;
指針的指針饵隙,指針式內(nèi)存中的對象,因此也有自己的地址沮脖,允許把指針的地址再存放到另一個指針之中金矛。
**表示指向指針的指針,int ival = 1024; int *pi = &ival; int \*\*ppi = π
所以如果要訪問最原始的那個對象勺届,需要對指針的指針做兩次解引用驶俊,**ppi。
指針的引用涮因,int i = 43; int *p; int *&r = p;//r是對指針p的引用废睦。 r = &i; *r = 0;
從右往左閱讀r的定義,離變量名最近的符號對變量的影響有最直接的影響养泡,因此r是一個引用嗜湃。*說明r引用的是一個指針。從右向左閱讀弄清楚真實含義
- const
const對象一旦創(chuàng)建后值就不能再改變澜掩,所以const對象必須初始化购披,const int i = 43;
默認情況下,const對象被設(shè)定為僅在文件內(nèi)有效肩榕,當多個文件中出現(xiàn)了同名的const變量時候刚陡,其實等同于在不同文件中分別定義了獨立的變量。
也可以在一個文件中定義const株汉,在其它多個文件中聲明并且使用它筐乳。const不管是聲明還是定義都添加extern關(guān)鍵字,這樣就只用定義一次乔妈。
extern const int bufSize = fcn();
用extern加以限定使其被其它文件使用蝙云。
extern const int bufSize;
extern限定,作用是指明bufSize并非本文件所獨有路召,它的定義將在別處出現(xiàn)勃刨。
- const的引用
const int ci = 1024; const int &r1 = ci;
引用及其對應的對象都是常量,引用和被綁定的對象關(guān)系是不變的股淡。
引用的類型必須與所引用的類型一致身隐,但是初始化常量引用允許使用任意表達式作為初始值,只要該表達式結(jié)果能轉(zhuǎn)換成引用的類型唯灵。
const int &r2 = 43;
,double dval = 3.14; const int &ri = dval;
確保ri綁定一個整數(shù)贾铝,編譯器進行了如下操作,const int temp = dval; const int &ri = temp;
ri綁定了一個臨時量對象。但是如果ri不是常量的話垢揩,那么此時綁定的對象是臨時量而不是dval大脉,所以這樣不能改變dval值,因此這樣行為是非法的水孩。
對const的引用可能引用一個并非const的對象int i = 43; const int &r2 = i;
指向常量的指針不能用于改變其所指對象的值,存放常量對象的地址琐驴,只能使用指向常量的指針俘种。
const double pi = 3.14; const double *cptr = π
指針的類型必須和所指向?qū)ο蟮念愋鸵恢拢窃试S令一個指向常量的指針指向一個非常量對象绝淡,double dval = 3.14; cptr = &dval;
指向常量的指針僅僅要求不能通過該指針改變對象的值宙刘。
const指針,常量指針說明指針存的值不能再改變了牢酵,不變的是指針本身的值而非指向的那個值悬包。int errNumb = 0; int *const curErr = &errNumb; const double pi = 3.14; const double *const pip = π//指向常量對象的常量指針
,從右往左讀,curErr是一個常量對象馍乙,*表示是常量指針布近,pip是一個常量指針,指向常量對象丝格。
- 頂層const
頂層const表示指針本身是一個常量撑瞧,底層const表示指針所指的對象是一個常量。用于聲明引用的const都是底層constconst int &r = ci;
當執(zhí)行對象的拷貝操作時候显蝌,拷入和拷處的對象必須具有相同的底層const資格预伺,或者兩個對象的數(shù)據(jù)類型必須能夠轉(zhuǎn)換。 - 常量表達式
值不會改變并且在編譯過程就能得到計算結(jié)果的表達式曼尊,const int max = 20; const int limit = max + 1;
constexpr變量酬诀,聲明為這種類型表示是一個常量,constexpr int mf = 20;
算術(shù)類型骆撇,引用和指針都屬于字面值類型瞒御,指的是編譯時候就能得到結(jié)果的類型。所以可以定義成constexpr類型艾船。
constexpr把它定義的對象置為了頂層const,constexpr int *q = nullptr;
q是常量指針葵腹。constexpr const int *p = &i;
p是常量指針,指向整形常量i
- 類型別名
typedef double wages; typedef wages base, *p;
wages是double的同義詞屿岂,base也是践宴,p是double *的同義詞。
別名聲明爷怀,using SI = Sales_item;
typedef char *pstring; const pstring cstr = 0; const pstring *ps;
指向char的常量指針
auto定義的變量必須有初始值阻肩,聲明多個變量的時候該語句的所有變量的初始基本數(shù)據(jù)類型必須一樣。
如果推斷出的auto類型是一個頂層const,那么const auto f = ci;
- decltype類型指示符
decltype作用是選擇并且返回操作數(shù)的數(shù)據(jù)類型,decltype(f()) sum = x;
sum的類型就是函數(shù)f的返回類型
如果表達式內(nèi)容是解引用操作烤惊,則decltype將得到引用類型乔煞,int i = 42, *p = &i; decltype(*p) c//必須初始化;
c的類型就是int &
變量名如果加上括號,編譯器會把它當成表達式柒室,所以decltype就會得到引用類型渡贾,decltype((i)) d;//d是int &必須初始化
- 頭文件
為了確保各個文件中類的定義一致,類通常被定義在頭文件中雄右,類所在頭文件的名字應與類的名字一樣空骚。Sales_data類定義在名為Sales_data.h的頭文件中。
頭文件包括那些只能被定義一次的實體擂仍,類囤屹,const,constexpr變量逢渔。
確保頭文件多次包含能安全工作的是預處理器肋坚,是在編譯前執(zhí)行的程序。
頭文件保護符肃廓,預處理變量有兩種狀態(tài)智厌,已定義和未定義,#define將名字設(shè)定為預處理變量亿昏,#ifdef當且僅當變量已經(jīng)定義時為真峦剔,#ifndef當且僅當變量未定義時候未真。直到用到#endif為止角钩。
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
struct Sales_data{
};
#endif```