Primer C 學習筆記 第二章

2021-09-27 11:34:43 字數 4528 閱讀 9599

本書為primer c++ 中文第五版

初始化與賦值

初始化的含義是建立變數時賦予其乙個初始值;

賦值的含義是把物件的當前值擦除,以乙個新值代替;

物件在建立的時候最好初始化

宣告與定義

宣告使得名字為程式所知,乙個檔案如果想要使用別處定義的名字必須包含對那個名字的宣告,宣告規定了變數的型別和名字;

定義負責建立與名字關聯的實體,不僅規定變數的型別和名字,還會申請儲存控制項,也可能會為變數賦乙個初始值。

//eg.

extern int i;//宣告

int j;//定義

extern double pi = 3.14159;//定義

變數能且只能被定義一次,但是可以被多次宣告引用

引用為物件起了另外乙個名字,引用一旦初始化完成,引用將和它的初始值物件一直繫結在一次,所以引用必須要初始化,引用型別的初始值必須是乙個物件。

在定義引用之後,對引用的一切操作都是在與之繫結的物件上進行的,因為引用本身不是乙個物件,不能定義引用的引用。

//eg.

int ival = 1024;

int &refval = ival;

指標

指標和引用一樣也實現了對其他物件的間接訪問,與引用不同的地方有以下幾個方面:

指標本身就是乙個物件,允許對指標賦值和拷貝,而且在指標的宣告週期內它可以先後指向幾個不同的物件;

指標無須在定義時賦初值,但是如果不初始化,將會擁有乙個不確定的值。

如果指標沒有指向任何具體物件,所有試圖訪問此指標物件的行為都不被允許

符號的多重含義

//eg.

int i = 42; //定義int型別的i值為42

int &r = i; //宣告r是乙個引用

int *p; //宣告p是乙個指標

p = &i; //&是乙個取位址符

*p = i; //*是乙個解引用符

int &r2 = *p; //宣告r2是乙個引用,*是乙個解引用符,其中r2的初始物件為i

int *&r3 = p; //宣告r3是乙個引用,*是乙個解引用符,其中r3的初始物件為p

void指標

是一種特殊的指標型別,可用於存放任意物件的位址。void指標只可以和別的指標比較、作為函式的輸入或輸出,或者賦給另外乙個void指標。不能直接操作void*指標所指的物件。

限定符const

關鍵字const是對變數的型別加以限定,使這個變數的值不能被改變,稱為常量。因為const物件一旦建立後其值不能被改變,所以const物件必須要初始化。

一般情況下,const物件僅在檔案內有效,如果多個檔案之間共享const物件,需加上extern關鍵字。

對const的引用也稱為常量引用。常量不可改變,因此常量引用也不可修改。

指向常量的指標不能用於改變其所指物件的值。想要存放常量物件的位址,只能使用指向常量的指標。

指向常量的指標可以指向乙個非常量物件,但是不能通過該指標改變物件的值

//eg.

int errnumb = 0;

int *const curerr = &errnumb;

//curerr將一直指向errnumb,errnumb是乙個一般的非常量整數,可以使用curerr去修改errnumb的值

const double pi = 3.14159;

const double *const pip = &pip;

//pip是乙個指向常量物件的常量指標,無論pip指向的物件值和自己存的位址都不能改變。

頂層const表示指標本身是個常量,底層const表示指標所指的物件是乙個常量。更一般的,頂層const表示任意的物件是常量,用於宣告引用的const都是底層const指向常量的指標,常量指標,指向常量的常量指標

希望知道的科普一下

//eg.

const int *p;

//指向常量的指標,指標"自以為是"的結果,他們覺得自己指向了常量。

//指標指向的值不可以通過此指標更改,但是可以更改指標的指向,也可以改變p1指標指向的值

int *const p;

//常量指標,一旦初始化之後,存放在指標中的那個位址就不能再改變,不變的是指標本身而非指向的值

//指標指向的值可以通過此指標更改,但是不可以更改指標的指向

const double *const pip

//指向常量的常量指標

//無論pip所指的物件還是pip自己儲存的地方在都不能改變

例項**

#includeint main(){

int a = 3;

int b = 4;

//指向常量的指標

const int *p1 = &a;

std::cout結果如下

3 31000 1000

1000 4

4 4100 100

型別別名

定義型別別名,傳統的方式是typedef,c++11定義了別名宣告。

//typedef

typedef double wages;

//別名宣告

using base = double;

//折騰半天記錄

typedef char *pstring;

const pstring cstr1 = 0;//cstr1是常量指標

const char * cstr2 = 0;//cstr2是指向常量的指標

//理解:const pstring cstr1 = 0 <==> char * const cstr1 = 0

//typedef不能簡單的替換

auto型別說明符

auto讓編譯器替我們分析表示式所屬的型別,通過初始值推算變數的型別。auto定義的變數必須有初始值。在一條一句宣告多個變數時,需要包中只有乙個基本資料型別。

auto一般會忽略頂層const,保留底層const。如果希望推斷出的auto型別是乙個頂層const,則需要明確指出,如: const auto f = (int) a;

decltype型別指示符

從表示式的型別推斷出要定義的變數的型別,但是不用該表示式的值初始化變數。

如果decltype使用的表示式是乙個變數,則返回該變數的型別。

如果decltype使用的表示式不是乙個變數,則返回表示式結果對應的型別。

decltype((variable))的結果永遠是引用,decltype(variable)結果只有當variable本身就是乙個引用的時候才是引用。

例項**

#includeint main()

{ int a = 3, b = 4;

decltype(a) c = a; //c是int的定義,賦初始值為a的值3

decltype((b)) d = a; //d是個int(b為int)引用,初始化物件為a,則d的值將和a一直保持一樣

std::cout結果如下

3 4 3 3

4 4 3 4

4 5 3 4

4 5 4 4

5 5 4 5

預處理器

確保標頭檔案多次包含之後仍能夠安全工作。

#include 用指定的標頭檔案的內容代替

#define 把乙個名字設定為預處理變數

#ifdef 當且僅當變數已定義時為真

#ifndef 當且僅當變數未定義時為真

#endif 當結果為真,執行操作到此為止

// 防止重複包含的寫法,最好都加上

//sales_data_h為預處理變數,如果沒有被定義則執行,如果已經被定義則忽略

#ifndef sales_data_h

#define sales_data_h

#endif

引用的型別必須與其所引用的物件型別一致;(兩個例外);page46

第一種例外是,初始化常量引用時允許用任意表示式作為初始值,只要改表示式能夠轉換成引用的型別即可。

指標的型別必須與其所指物件的型別一致;(兩個例外);page47

第乙個例外是,允許令乙個指向常量的指標指向乙個非常量物件。

const指標不變的是指標本身的值,也就是存放在指標中的位址。而不是指標指向的那個值。

第二章學習筆記

在c 中,陣列下標從0開始,而不是1.c 不支援陣列的抽象,也不支援對整個陣列的操作。在c 中,物件可以靜態分配 即編譯器在處理程式源 時分配,也可以動態分配 即程式執行時,用執行時刻庫函式來分配。靜態與動態記憶體分配的兩個主要區別是 1 靜態物件是有名字的變數,可以直接對你進行操作。而動態物件是沒...

第二章學習筆記

ansi c 有翻譯和執行兩種環境,且不必在一台機器上,例如交叉編譯器 cross compiler 作業系統也是如此 freestanding environment 翻譯 將源 轉換為可執行機器指令 執行 實際執行 翻譯經過以下階段 形成的目標檔案字尾可能在不同系統下不同,如 o obj cc ...

第二章筆記

1.遞迴查詢和迭代查詢 遞迴查詢是一條環路,直接想成遞迴的定義就行,你想查乙個 的ip,首先將這個 傳給它的本地dns,然後認為本地dns可以直接將ip給你,然後本地dns為了知道這個ip又詢問下個dns伺服器。從此可以看出,增加了被涉及的伺服器的資料,所以一般用迭代查詢,迭代查詢是你詢問完後給你下...