C++中文版本primer 第二章變量和基本類型 學習筆記

2.2變量

2.2.1 變量定義

列表初始化

  • 定義一個名字為units_sold的int變量并初始化為0
int units_sold = 0;
int units_sold = {0};
int units_sold{0};
int units_sold(0);
  • C++11 用花括號來初始化變量,上面這個步驟也稱之為列表初始化。這種初始化有一個重要的特點,如果在初始化信息的時候存在丟失信息的風險那么編譯器就會報錯。丟失信息,是指在逆類型轉換的時候,丟失數據的精度。
long double ld = 3.241592653;int a {ld}, b = {ld}; //錯誤,轉化未執行,因為存在丟失信息的風險int c(ld), d = ld;    //正確,轉換執行,但是會丟失部分數值

默認初始化

  • 如果定義變量沒有指定初始值,則變量會默認初始化。初始化是由于變量的類型(標準類型/自定義類型)和所處的位置所決定的。定義在任何函數體之外的變量會被初始化為0。
  • 定義在函數體之內的變量不會被初始化,其數值是未被定義的,如果試圖拷貝或者以其他方式來訪問這個數值是會引發錯誤。
  • 類的對象如果沒有顯示的初始化,則其數值由類確定。

2.2.2 變量聲明和定義的關系

  • C++使用分離式編譯機制,該機制允許將程序分割為若干個文件,每個文件都可以被獨立的編譯。簡單的例子就是,頭文件的使用,使得程序代碼之間可以互相共享代碼。如引用頭文件iostream,調用輸入輸出函數std::out。
  • 為了支持分離式編譯機制,C++將聲明和定義區分開來。聲明使得程序的名字被程序所知,定義負責創建與名字相互關聯的實體。變量聲明規定了變量的類型和名字,這一點上定義與之相同。除此之外,定義還申請存儲空間,也可能會給變量賦予一個初始化的數值。
  • 如果想聲明變量但不定義它,在變量的名字之前使用extern關鍵字,而且不要顯示的初始化變量。
extern int i; //聲明i,并非定義i
int j;  //聲明并未定義了j
  • 任何包含了顯示初始化的聲明就會變成了定義。當然也可以使用extern標記的變量賦一個初始化的數值,這就會抵消了extern的作用,一旦初始化就叫定義。
  • 變量只可以被定義一個,但是可以多次聲明。

2.2.3 標識符

  • 用戶自定義的標識符不可以連續出現兩個下劃線,也不可以使用下劃線緊連大寫字母開頭,定義函數體外的標識符也不可以以下劃線開頭。

變量的命名規范

  • 標識符要體現實際的含義
  • 變量名使用小寫
  • 用戶自定義的類名一般使用大寫
  • 如果用戶定義的標識符由多個單詞組成,則單詞之間要有明顯的區分。

名字的作用域

  • 作用域是程序的一部分,一般使用花括號進行分割。同一個名字在不同的作用域里面,可能指向不同的實體。名字的有效作用域始于名字的聲明語句,結束于聲明語句所在的作用域末端。

2.3 符合類型

2.3.1 引用

  • 引用為對象起了另外一個名字,引用類型引用另外一種類型。通過將聲明符號寫成&d的形式來引用類型,其中d是聲明的變量名字。初始變量的時候,初始數值會被拷貝到新建的對象中。定義引用的時候,程序把引用和初始值綁定在一起,而不是將初始值拷貝給引用。一旦初始化完成,引用將和他的初始值綁定在一起。因為無法使引用重新綁定到另外一個對象,因此引用必須要初始化。
  • 引用并非對象,它只是為一個已經存在的對象所起的另外一個名字。
  • 引用不是一個對象,因此無法定義引用的引用。
  • int &a = 10; //錯誤,引用類型的初始值必須是一個對象
  • double dav = 3.15; int &rte = dav;錯誤,引用類型和被引用的對象的類型必須是一致的。
int ival = 1024;
int &refVal = ival;// refVal指向ival(是ival的另外一個名字)
int &refVal2 ;//錯誤,引用必須被初始化

2.3.2 指針

  • 指針是指向的另外一種類型的符合類型。和引用是類似的,指針也實現了對于其他對象的間接訪問。
  • 指針本身就是一個對象,允許對于指針賦值和拷貝,而且指針的生命周期內可以先后指向相同類型的不同對象;指針無需在定義的時候進行賦值,和其他類型是一樣的,在塊作用域內定義的指針如果沒有被初始化,也將擁有一個不確定的數值。
  • 引用不是對象,沒有實際的地址,因此不能定義指向引用的指針。
double dval;
double *pd = &dval;// 正確,初始值是double類型的對象地址
double *pd2 = pd;//   正確,初始值是指向double對象的指針

指針值

指針的值(即地址)應屬于以下幾種狀態之一

  • 指向一個對象
  • 指向緊領對象所占空間的下一個位置
  • 空指針,意味著指針沒有指向任何對象
  • 無效指針,也就是上面所述情況之外的其他數值

利用指針指向對象

  • 如果指針指向了一個對象,則可以允許使用解引用符*來訪問該對象
  • 解引用操作適用于那些確定了指向某個對象的有效指針
int val = 42;
int *p = &val;//p存放著變量val的地址,或者說p是指向變量val的指針
cout << *p;   //由符號*得到指針p所指的對象,輸出42

空指針

  • null pointer不指向任何對象,在試圖使用一個指針之前的代碼可以首先檢查指針是否為空。以下是檢查指針是否為空的方法

int *p1 = nullptr; //等價于int *p1 = 0;
int *p2 = 0;       //直接將p2初始化字面常量0
int *p3 = NULL;    //需要首先使用#include<cstdlib>  等效于int *p3 = 0
  • 使用nullptr字面值來初始化指針,這是一種特殊類型的字面值,可以被轉化為任意其他的指針類型。另一種方法就如對p2的定義一樣,也可以將指針初始化為字面值0來生成指針。

void*指針

  • void*是一個特殊的指針類型,用于存放人以對象的地址。一個void*指針可以存放一個地址,這個和其他地址是類似的。

  • void*指針的功能單一,拿他和別的指針比較、作為函數的輸入和輸出、或者賦值給另外一個void*指針,但是不可以直接操作這個void*所指的對象。

2.3.3 理解復合類型的聲明

定義多個變量

  • int * p1,p2;//p1是指向int的指針,p2是單純的int

指向指針的指針

指向指針的引用

2.4? const限定符

  • const對象一旦創建后其數值就不會被再次改變,因此const對象必須初始化。
  • const對象只在文件中有效
  • 在不同的文件中使用不同的const來定義不同的常量,那么每個文件定義的變量只會在自己所屬的文件中有效。如果想讓多個文件共享同一個const變量,那么使用關鍵字extern即可

2.4.1 const的引用

把引用綁定到const對象上,就像綁定到其他對象上一樣,稱之為對于常量的引用。和普通信用不同,對于常量的引用不能被用于修改它所綁定的對象。

const int ci = 1024;
const int &r1 = ci;//正確,引用及其對應的對象都是常量
r1 = 42;          //錯誤,r1是對于常量的引用
int &r2 = ci;     //錯誤,試圖讓一個非常量去引用一個常量對象  
  • 因為不允許直接為ci賦值,當然也不可以通過引用去改變ci,因此,對于r2的初始化是錯誤的,假設初始化合法,就可以通過r2來改變他引用的對象的數值,這顯然是不正確的。

初始化和對const的引用

  • 引用的類型必須和其所引用對象的類型是一致的,但是有兩個例外。1,初始化常量引用時候允許用任意表達式來作為初始化的數值,只要該表達式結果可以轉化為引用的類型即可。尤其,允許一個常量引用綁定非常量的對象、字面值甚至是一個一般表達式。

    int i = 42;const int &r1 = i; //允許將const int& 綁定到一個普通int對象上const int &r2 = 42;//r2是一個常量的引用const int &r3 = r1 * 2;//r3是一個常量的引用int &r4 = r1 * 2;  //錯誤,r4是一個普通的非常量的引用

對const引用可能引用一個并非const的對象

  • 常量的引用僅僅對于可以引用可以參與的操作進行了限定,對于引用的對象的本身是不是一個常量未做限定。因為對象也可能是一個非常量,所以可以通過其他途徑來改變它的值。

    int i = 42;int &r1 = i; //引用r1綁定對象iconst int &r2 = i;//r2也綁定對象i,但是不允許通過r2來修改i的數值r1 = 0; //r1并非常量,i的數值修改為0r2 = 0; //錯誤,r2是一個常量的引用,因此不可以修改引用的元素的數值

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447076.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447076.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447076.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

內存池中的嵌入式指針

嵌入式指針 可以union改struct 內存分配后 next指針就沒用了 直接作為數據空間比較省內存 因為對指針指向的內存存儲的時候 編譯器是不管你是什么類型的 &#xff0c;這里有道練習題可以對指針的概念稍微理解一下&#xff1a; #include <iostream> using std::cout; us…

C++ 標準程序庫std::string 詳解

現在一般不再使用傳統的char*而選用C標準程序庫中的string類&#xff0c;是因為string標準程序和char*比較起來&#xff0c;不必擔心內存是否足夠、字符串長度等等&#xff0c;而且作為一個類出現&#xff0c;集成的操作函數足以完成大多數情況下(甚至是100%)的需要。比如&…

內存池的實現4 alloc內存池

alloc 內存池 優點: &#xff1a;本質是定長內存池的改進&#xff0c;分配和釋放的效率高。可以解決一定長度內存分配的問題。 缺點 &#xff1a;存在內碎片的問題&#xff0c;且將一塊大內存切小以后&#xff0c;申請大內存無法使用&#xff0c;別的FreeList掛了很多空閑的內存…

C++primer第15章節詳解面向對象程序設計

前言 面向程序設計基于三個基本概念&#xff1a;數據抽象、繼承和動態綁定。繼承和動態綁定可以使得程序定義與其他類相似但是不完全相同的類&#xff1b;使用彼此相似的類編寫程序時候&#xff0c;可以在一定程度上忽略掉他們的區別。 OOP概述 oop&#xff08;面向程序的設…

內存池的線程安全問題

malloc/free 據說老版本libc 有倆個版本&#xff0c;當你連接 pthread庫的時候它就鏈接的是線程安全版&#xff0c;否則不是。在glic 2.2 以上無論怎么都是線程安全的。 new/delete new/delete 封裝的 malloc/free , 如果malloc/free 是它們就是線程安全的。

C++11命名空間的using說明

std::cin 表示從標準輸入讀取內容&#xff0c;此處的作用域操作符::是指編譯器應該從左側名字所示的作用域中尋找右側那個名字。因此std::sin表示使用命名空間std中的cin。 每個名字都需要有獨立的using的聲明 每一個using聲明引入命名空間中的一個成員&#xff0c;比如可以將…

c語音的一些特殊關鍵字

PRETTY_FUNCTION C語言中獲取函數名 C語言中的__LINE__用以指示本行語句在源文件中的位置信息

C++ primer三章二節標準庫類型string

標準庫類型string 標準庫類型string表示可變長的字符序列&#xff0c;使用#include<string>引入頭文件&#xff0c;string定義在命名空間std中。 定義和初始化string對象 如何初始化類的對象是由類的本身決定的&#xff0c;類可以定義很多初始化對象的方式&#xff0c;…

vim 不常見但好用的命令

● 跳躍 ○ 向前跳躍是 f ○ 向后跳躍是 F ● 繼續 ○ 保持方向是 ; ○ 改變方向是 , ● 可以加上 [count] 來加速 ● ^ 是到本行第一個非空字符 ● 0 是到本行第一個字符&#xff0c;不管是不是空格 ● g_ 是到本行最后一個非空字符 ● 兩個按鍵要依次按下 ● $ 跳到本行最后…

加密機組會 會議紀要

2020年9月28日 1&#xff0c;使用基類繼承的機制&#xff0c;調用寫好的函數接口 1&#xff0c;不要 使用Content&#xff08;封裝數據&#xff0c;本質是一個json字符串&#xff09;&#xff0c;1&#xff0c;因為每次使用這個需要對里面的內容進行序列化&#xff0c;轉化成…

c++為什么沒有垃圾回收

垃圾回收 內存清理的另一個方面是垃圾回收。在支持垃圾回收的環境中&#xff0c;程序員幾乎不必顯式地釋放與對象關聯的 內存。運行時庫會在某時刻自動清理沒有任何引用的對象。 與C#和Java不一樣&#xff0c;在C語言中沒有內建垃圾回收。在現代C中&#xff0c;使用智能指針管理…

C++ Vecctor容器淺析

Vector的定義 向量&#xff08;Vector&#xff09;是一個封裝了動態大小數組的順序容器&#xff08;Sequence Container&#xff09;。跟任意其它類型容器一樣&#xff0c;它能夠存放各種類型的對象。可以簡單的認為&#xff0c;向量是一個能夠存放任意類型的動態數組。vector…

C++primer第二章2.4節對于const限定符相關內容進行詳解

const限定符 const對象一旦創建后其數值就不會被再次改變&#xff0c;因此const對象必須初始化。const對象只在文件中有效在不同的文件中使用不同的const來定義不同的常量&#xff0c;那么每個文件定義的變量只會在自己所屬的文件中有效。如果想讓多個文件共享同一個const變量…

二分法的常見問題

mid(leftright)/2; mid (high - low) / 2 low; 這樣寫可以防止left right溢出 ,不過數足夠大是時候該溢還是溢 為什么要取右邊中間數呢&#xff1f;這是因為在區間里 只有 2 個元素的時候&#xff0c;把[left…right]劃分成[left…mid - 1]和[mid…right]這兩個區間&#x…

演示IPFS的一個完整的流程以及針對部分概念的詳解

整體的流程 1&#xff0c;創建ipfs節點 通過ipfs init在本地計算機建立一個IPFS節點本文有些命令已經執行過了&#xff0c;就沒有重新初始化。部分圖片拷貝自先前文檔&#xff0c;具體信息應以實物為準 $ ipfs init initializing IPFS node at /Users/CHY/.ipfs generating 2…

c++ 算法的時間復雜度

一般ACM或者筆試題的時間限制是1秒或2秒。 在這種情況下&#xff0c;C代碼中的操作次數控制在 10^7為最佳。 下面給出在不同數據范國下&#xff0c;代碼的時間復雜度和算法該如何選擇&#xff1a; 1.n≤ 30,指數級別&#xff0c;dis剪枝&#xff0c;狀態壓縮dp 2.n < 100 &g…

簡單工廠模式實現計算器

#include <iostream> #include <vector> #include <string> #include <iostream> #include <map> using namespace std; #define __THROW_ZERO do {cerr << "The dividend is 0" << endl; exit(1);}while(0);/* 簡單工廠處…

TDengine安裝教程

TDengine安裝教程 前言 TDengine的安裝十分簡單&#xff0c;可以有以下三種安裝方式&#xff0c;源碼安裝、通過Docker容器進行安裝、通過安裝包進行安裝。但是使用源碼安裝較為復雜&#xff0c;通過docker的方式最為簡單&#xff0c;但是需要一定docker相關的知識&#xff0…

C++中size_t的學習

size_t的定義 size_t是一種數據相關的無符號類型&#xff0c;它被設計得足夠大以便能夠存儲內存中任意對象的大小。設計 size_t 就是為了適應多個平臺&#xff0c;size_t等效于unsigned short int 或者 unsigned long int 類型&#xff0c;這個過程是動態匹配的。在需要通過數…

策略模式解決商店打折問題

#include <bits/stdc.h> using namespace std; /*策略模式解決商店打折問題*/class Cashsuper { private:/* data */ public:virtual double addcash(double cash) 0;double Getresult(double money){return addcash(money);} };class Cashnormal : public Cashsuper {p…