C++之復合資料型態 第一部(參考 列舉 指標)

復合資料型態(compound type) 是由其他資料型態(data type) 定義出來的型態, C++ 中的復合資料型態包括參考(reference) 、列舉(enumeration) 、陣列(array) 、指標(pointer ) 、結構(structure) 及聯合(union) 。

參考

參考是變數(variable) 的別名(alias) ,例如

#include <iostream>int main() {int a = 22;int& a_ref = a;std::cout << "a: " << a << std::endl;std::cout << "a_ref: "<< a_ref << std::endl;a_ref = 11;std::cout << "a: " << a << std::endl;std::cout << "a_ref: " << a_ref << std::endl;return 0;
}

? 第5 行,宣告參考的型態(type) 必須與參考所指向的變數型態相同,然后在型態名稱后后使用& 運算子(operator) 標明這是個參考變數,因此這個例子的參考變數為a_ref,等號右邊為所要指向的變數,此例為a ?

int& a_ref = a;

由于C++ 是自由格式的程式語言,因此寫成int & a_ref或int &a_ref都可以。

接下來我們印出aa_ref的值,然后把a_ref改成11

a_ref = 11;

這樣a也會變成11,編譯后執行結果如下

$ g++ u0701_1.cpp
$./a.out 復制代碼
答:22
參考編號:22
答:11
參考編號: 11
$

由上可看出參考等同于原來的變數,這被稱為左值參考(lvalue reference) 。 C++11 增加了一個右值參考(rvalue reference) ,用以增進運算的效率,這是用&&來宣告,例如

int&& ref = a + b + c;

右值參考是對運算式的參考,舉例如下

#include <iostream>int main() {int a = 22;int b = 33;int c = 11;int&& ref = a + b + c;std::cout << "a: " << a << std::endl;std::cout << "b: " << b << std::endl;std::cout << "c: " << c<< std::endl;std::cout << "ref: " << ref << std::endl;ref += 66;std::cout << "a: " << a << std::endl;std::cout << "b: "<< b << std::endl;std::cout << "c: " << c << std::endl;std::cout << "ref: " << ref << std::endl;return 0;
}

編譯后執行,結果如下

$ g++ u0701_2.cpp -std=c++0x
$./a.out 復制代碼
答:22
乙:33
額: 11
參考:66
答:22
乙:33
額: 11
參考:132
$

列舉

列舉是一組整數常數,例如

#include <iostream>int main() {enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};std::cout << "Sunday: " << Sunday << std::endl;std::cout << "Monday: " << Monday << std::endl;std::cout << "Tuesday: " << Tuesday << std::endl;std::cout << "Wednesday: " << Wednesday << std::endl;std::cout << "Thursday: " << Thursday << std::endl;std::cout << "Friday: " << Friday << std::endl;std::cout << "Saturday: " << Saturday << std::endl;Day today = Wednesday;std::cout << today << std::endl;return 0;
}

第4 行,定義一個列舉型態Day,使用關鍵字(keyword) enum,后面接著型態名稱Day,然后大括弧中是列舉的識別字(identifier) ,這被稱為非作用域列舉(unscoped enumeration )

enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

列舉常數為從0開始遞增的整數常數數列,因此第30 行宣告的today亦為整數常數,Wednesday是第4 個值,所以是整數3

Day today = Wednesday;

編譯執行,結果如下

$ g++ u0702_1.cpp
$./a.out 復制代碼
周日:0
星期一:1
星期二:2
星期三:3
星期四:4
周五:5
星期六:6
今天:3
$

列舉也可以匿名(anonymous) 與指定起始整數,例如

#include <iostream>int main() {enum {apple, banana = 11, orange, peach = 5};std::cout << "apple: " << apple << std::endl;std::cout << "banana: " << banana << std::endl;std::cout << "orange: " << orange << std::endl;std::cout << "peach: " << peach << std::endl;return 0;
}

此例的列舉沒有識別字,另外將banana設定為11,因此orange就由11遞增為12,最后的peach則設定為5

enum {apple, banana = 11, orange, peach = 5};

編譯后執行,結果如下

$ g++ u0702_2.cpp
$./a.out 復制代碼
蘋果:0
香蕉:11
橙色:12
桃子:5
$

列舉也可以跟struct或class一起宣告,形成作用域列舉(scoped enumeration) ,例如

enum class Color {RED, GREEN, BLUE};

C++11 中,列舉常數可以改用其他型態,此時要在列舉識別字后面加上冒號及型態名稱,舉例如下

#include <iostream>enum class Color: char {RED = 'r',GREEN = 'g',BLUE = 'b',
};int main() {Color r;r = Color::RED;Color g;g = Color::GREEN;Color b;b = Color::BLUE;std::cout << "RED: " << static_cast<char>(r) << std::endl;std::cout << "GREEN: " << static_cast<char>(g) << std::endl;std::cout << "BLUE: " << static_cast<char>(b) << std::endl;return 0;
}

這里定義一個作用域列舉,并且將列舉常數的型態指定為char

enum class Color: char {RED = 'r',GREEN = 'g',BLUE = 'b',
};

編譯后執行,結果如下

$ g++ u0702_3.cpp -std=c++0x
$./a.out 復制代碼
紅色:r
綠色:g
藍色:b
$

指標

指標是儲存記憶體位址(address) 的資料型態,例如

#include <iostream>int main() {int a = 22;int* a_ptr = &a;std::cout << "a_ptr: " << a_ptr << std::endl;std::cout << "*a_ptr: " << *a_ptr << std::endl;return 0;
}

第5 行,宣告指標的型態,必須與指標所指向的變數型態相同,然后在型態名稱后使用* 運算子標明這是個指標變數,因此這個例子的參考變數為a_ptr,等號右邊為所要指向的變數,此例為a,a之前的&則是取址運算子(address-of operator)

int* a_ptr = &a;

由于C++ 是自由格式的程式語言,因此寫成int?* a_ptrint?*a_ptr都可以。

接下來先印出a_ptr的值,然后利用反參考運算子(dereference operator)?*取得a_ptr所指向變數的值

std::cout << "a_ptr: " << a_ptr << std::endl;
std::cout << "*a_ptr: " << *a_ptr << std::endl;

編譯后執行,結果如下

$ g++ u0704_1.cpp
$./a.out 復制代碼
a_ptr:0x7fff50b81b08
*a_ptr: 22
$

注意,編譯器(compiler) 會依據運算子出現的位置判斷運算子的用途,例如

int* a_ptr; // 定義a_ptr為指標變數
int& a_ref; // 宣告 a_ref 為參考變數
a_ptr = &a; // & 為取地址侵犯子,取得一個的記憶體位址
*a_pr = 36; // * 為反參考進攻子,將設定為36

陣列識別字其實就是個指標,另外指標也可以作算術運算,例如

#include <iostream>int main() {int a[] = {1, 2, 3, 4, 5};std::cout << "a[2]: " << *(a + 2) << std::endl;std::cout << "a[4]: " << *(a + 4) << std::endl;return 0;
}

這里用陣列名稱與反參考運算子取得元素,指標的算術運算如同陣列的索引值,由于陣列名稱為第1 個元素索引值為0的記憶體位址,所以加2就是索引值為2的元素記憶體位址,也就是第3 個元素,加4就是索引值為4的元素記憶體位址,也就是第5 個元素

std::cout << "a[2]: " << *(a + 2) << std::endl;
std::cout << "a[4]: " << *(a + 4) << std::endl;

編譯后執行,結果如下

$ g++ u0704_2.cpp
$./a.out 復制代碼
a[2]: 3
a[4]: 5
$

事實上,所有指標都預設能隱性轉換指向void,舉例如下

#include <iostream>int main() {int n = 1;int* p = &n;void* p2 = p;int* p3 = static_cast<int*>(p2);std::cout << "n: " << n << std::endl;std::cout << "p: " << p << std::endl;std::cout << "*p3: " << *p3 << std::endl;return 0;
}

這里將指向int的指標重新指派給指向void的指標,轉換回來要利用關鍵字 static_cast

int* p = &n;
void* p2 = p;
int* p3 = static_cast<int*>(p2);

編譯后執行,結果如下

$ g++ u0704_3.cpp
$./a.out 復制代碼
數量:1
p: 0x7fff55f89b18
*p3:1
$

C++11 新增一個關鍵字nullptr表示空的指標,等同于巨集NULL,舉例如下

#include <iostream>int main() {int n = 22;std::cout << "n: " << n << std::endl;int* p = &n;std::cout << "p: " << p << std::endl;p = nullptr; // NULLstd::cout << "p: " << p << std::endl;return 0;
}

編譯后執行,結果如下

$ g++ u0704_4.cpp
$./a.out 復制代碼
人數:22
p: 0x7fff503acae8
p: 0x0
$

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

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

相關文章

GuLi商城-商品服務-API-品牌管理-OSS獲取服務端簽名(續)

如何進行服務端簽名直傳_對象存儲(OSS)-阿里云幫助中心 gulimall-third-party服務的代碼: package com.nanjing.gulimall.thirdparty.controller;import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.utils.BinaryUtil; impor…

Linux開發:Fuse介紹

Fuse(filesystem in userspace),是一個用戶空間的文件系統。通過fuse內核模塊的支持&#xff0c;開發者只需要根據fuse提供的接口實現具體的文件操作時所對應的回調函數&#xff0c;就可以實現一個文件系統。由于其主要實現代碼位于用戶空間中&#xff0c;因此不需要重新編譯內…

實時數倉項目需求及架構設計

第2章實時數倉項目需求及架構設計 2.1 項目需求分析 1&#xff09;采集平臺 ? &#xff08;1&#xff09;用戶行為數據采集平臺搭建 ? &#xff08;2&#xff09;業務數據采集平臺搭建 2&#xff09;離線需求 … 2.2 項目框架 2.2.1 技術選型 ? 技術選型主要因素&a…

15 - matlab m_map地學繪圖工具基礎函數 - 一些數據轉換函數(二)

15 - matlab m_map地學繪圖工具基礎函數 - 一些數據轉換函數&#xff08;二&#xff09; 0. 引言1. 關于m_geodesic2. 關于mygrid_sand23. 結語 0. 引言 通過前面篇節已經將m_map繪圖工具中大多繪圖有關的函數進行過介紹&#xff0c;已經能夠滿足基本的繪圖需求&#xff0c;本節…

探索 `DatagramSocket` 類

DatagramSocket 類是 Java 網絡編程中的一個關鍵組件&#xff0c;專門用于處理 UDP&#xff08;用戶數據報協議&#xff09;通信。與基于連接的 TCP 不同&#xff0c;UDP 是一種無連接協議&#xff0c;適用于對速度和效率要求較高&#xff0c;但對可靠性要求相對較低的場景。 …

【JavaScript】包裝類

包裝類 JS 提供了三個主要的包裝類&#xff1a;String、Number、Boolean。如果嘗試把原始類型&#xff08;string、number、boolean&#xff09;數據當成對象使用&#xff0c;JS 會自動將其轉換為對應包裝類的實例。 我們先來看一下 “基本類型數據” 及 “其包裝類的實例” …

個人倒計時頁面源碼,實用倒計時單頁源碼

一、源碼描述 這是一款非常實用的個人倒計時頁面&#xff0c;支持設置未來一年時間&#xff0c;支持設置背景音樂&#xff0c;支持自定義下拉頁面&#xff0c;點擊向下箭頭查看。 二、源碼截圖 三、源碼下載

docker 常用命令,后面不斷更新

1.從Docker容器中下載文件到本地的方法 使用 docker cp 命令:該命令可以將文件或目錄從容器復制到主機。該方法簡單快捷&#xff0c;適用于少量文件的下載。 # 將容器名為my_container中的 /data/file.txt文件復制到本地/path/to/save/file.txt docker cp my_container:/data/…

深入探討【C++容器適配器】:現代編程中的【Stack與Queue】的實現

目錄 一、Stack&#xff08;棧&#xff09; 1.1 Stack的介紹 1.2 Stack的使用 1.3 Stack的模擬實現 二、Queue&#xff08;隊列&#xff09; 2.1 Queue的介紹 2.2 Queue的使用 2.3 Queue的模擬實現 三、容器適配器 3.1 什么是適配器 3.2 為什么選擇deque作為stack和…

kylin入門教程

Apache Kylin的入門教程主要涵蓋以下幾個方面&#xff1a; 一、Apache Kylin簡介 Apache Kylin是一個開源的分布式分析引擎&#xff0c;提供Hadoop之上的SQL接口及多維分析&#xff08;OLAP&#xff09;能力以支持超大規模數據。最初由eBay Inc.開發并貢獻至開源社區&#xf…

基于Vue和UCharts的前端組件化開發:實現高效、可維護的詞云圖與進度條組件

基于Vue和UCharts的前端組件化開發&#xff1a;實現高效、可維護的詞云圖與進度條組件 摘要 隨著前端技術的迅速發展和業務場景的日益復雜&#xff0c;傳統的整塊應用開發方式已無法滿足現代開發的需求。組件化開發作為一種有效的解決方案&#xff0c;能夠將系統拆分為獨立、…

Shell基礎之函數和數組

目錄 函數 什么是函數 函數的語法 函數的調用 函數的返回值 函數的案例 函數變量的作用域 遞歸函數 函數庫文件 數組 定義數組語法 數組操作 獲取所有元素 獲取元素下標 獲取數組長度 獲取數組元素 數組添加元素 刪除數組元素 刪除數組 遍歷數組元素 數組案…

解決pycharm無法識別miniconda

解決pycharm無法識別miniconda 找到miniconda安裝目錄下condabin/conda.bat文件&#xff0c;點擊load即可識別codna環境 a環境

Spring Boot(七十九):SprngBoot整合Apache tika做文件類型檢測

之前有一個章節介紹了Apache tika實現文檔內容解析,地址如下:Spring Boot(六十八):SpringBoot 整合Apache tika 實現文檔內容解析_springboot tika pptx-CSDN博客 下面我們介紹Apache tika實現文件類型檢測 1 引入依賴 <dependency><groupId>org.apache.tika&…

Docker 掛載目錄空間占滿修改/var/lib/docker/overlay2 的路徑解決方案

本文詳細描述了在CentOS7系統中卸載舊版Docker、安裝依賴、添加Docker源、配置存儲路徑并啟動Docker&#xff0c;使其在/home目錄下運行的過程。 以下是在CentOS 7下重新安裝Docker并將其安裝在/home/下的完整步驟&#xff1a; 卸載舊版本的Docker。如果您之前已經安裝了Dock…

仕考網:沒有學位證能考公務員嗎?

公務員考試需要滿足報名條件才能參加&#xff0c;沒有學位證能考公嗎? 沒有學位證書的考生也有機會參與公務員考試雖然可以選擇的崗位比較少&#xff0c;但可以報考參加那些不設定學位要求的崗位。當發布的公務員招錄信息中某一職位的學位要求標注為“無要求”時&#xff0c;…

【C++】:繼承[下篇](友元靜態成員菱形繼承菱形虛擬繼承)

目錄 一&#xff0c;繼承與友元二&#xff0c;繼承與靜態成員三&#xff0c;復雜的菱形繼承及菱形虛擬繼承四&#xff0c;繼承的總結和反思 點擊跳轉上一篇文章&#xff1a; 【C】&#xff1a;繼承(定義&&賦值兼容轉換&&作用域&&派生類的默認成員函數…

MATLAB Gazebo聯合仿真

準備仿真環境&#xff1a;在Gazebo中設置仿真場景&#xff0c;包括機器人模型、環境布局、傳感器和執行器等。編寫MATLAB腳本&#xff1a;在MATLAB中編寫控制算法和數據處理腳本&#xff0c;用于接收Gazebo中的傳感器數據&#xff0c;并生成控制命令。建立通信&#xff1a;通過…

DEBUG:jeston卡 遠程ssh編程

問題 jeston 打開網頁 gpt都不方便 而且只需要敲命令就行 解決 下載MobaXterm(window執行) liunx需要虛擬機 軟件 遠程快速復制命令

PHP文字ocr識別接口示例、人工智能的發展

全球在人工智能升級的大背景下&#xff0c;有一定規模的制造商開始大量部署人工智能機器人、系統&#xff0c;以此取代危險、簡單和重復性的工作。各種人工智能技術的迅猛發展&#xff0c;正在驅動各行業就業市場發現變革。 京東物流大家并不陌生&#xff0c;京東快遞機器人在…