數據結構:數組(Array)

目錄

什么是數組(Array)?

🔍為什么數組的下標要從 0 開始??

一、內存地址與偏移量的關系:從 0 開始是最自然的映射

二、指針的起點就是第 0 個元素的地址

三、歷史原因:BCPL → B → C → C++

數組的內存體現

?數組的聲明

數組的訪問方式?


什么是數組(Array)?

數組(Array)是 C++ 中的一種線性數據結構,用于存儲多個相同類型的變量,并且這些變量在內存中是連續排列的。

你可以把它想象成一個排好隊的儲物柜,每個柜子有編號(下標),每個柜子里放著一個值。例如:

int arr[5] = {10, 20, 30, 40, 50};

這表示我們聲明了一個包含 5 個 int 類型的數組,它依次存儲:

  • arr[0] = 10

  • arr[1] = 20

  • arr[2] = 30

  • arr[3] = 40

  • arr[4] = 50

注意:數組的下標從 0 開始,而不是 1。


🔍為什么數組的下標要從 0 開始??

雖然最初很多人覺得「從 1 開始」更符合直覺,但數組從 0 開始其實是有深刻的底層原因和效率考量,它與 指針、地址計算、語言設計哲學 有關。我們來系統解釋這個設計邏輯。?

一、內存地址與偏移量的關系:從 0 開始是最自然的映射

在 C/C++ 中,數組實際上是指針加偏移(pointer arithmetic)。

例子:

int A[4] = {10, 20, 30, 40};

假設數組 A 從地址 0x1000 開始,且每個 int 占 4 字節。

下標 i內存地址數學計算
A[0]0x1000A + 00x1000 + 0 * 4
A[1]0x1004A + 10x1000 + 1 * 4
A[2]0x1008A + 20x1000 + 2 * 4

?訪問 A[i] 實際上是計算:

*(A + i)  // 指針 + 偏移量

?👉 如果下標從 1 開始,那就必須寫成:

*(A + (i - 1))

?這樣會多一個運算(減法),無論在運行效率還是語義上都不自然。

二、指針的起點就是第 0 個元素的地址

當你聲明:int A[5];

數組名 A 實際上是指向 A[0] 的地址。不是 A[1],不是別的起點。

所以,

*A     == A[0]
*(A+1) == A[1]
*(A+2) == A[2]

?如果下標從 1 開始,就會出現“偏移一格”的矛盾,代碼會更難維護。

三、歷史原因:BCPL → B → C → C++

🧬 C語言起源于 B 和 BCPL

最早的語言 BCPL 和 B語言 中沒有數組的概念,只有“地址 + 偏移”。C 語言繼承了這種偏移訪問模型,所以自然地,數組從 0 開始偏移。

Dennis Ritchie(C 語言的設計者)就是遵循這個簡潔、底層直觀的設計哲學。

現代語言很多也從 0 開始

大多數現代語言也繼承了這個設計:

語言數組是否從 0 開始
C? 是
C++? 是
Java? 是
Python? 是
JavaScript? 是
Rust? 是

雖然也有一些語言(如 Fortran、Lua)允許你從 1 開始索引,但這并不常見。


數組的內存體現

數組的核心特征是:所有元素在內存中是挨著排放的,沒有任何間隔。

我們用一個直觀的內存圖解來說明:

假設 int 類型占用 4 字節(常見情況),數組如下:

int arr[4] = {100, 200, 300, 400};

?如果 arr[0] 存儲在內存地址 0x1000,那么在內存中是這樣的:

內存地址       值
0x1000      arr[0] = 100
0x1004      arr[1] = 200
0x1008      arr[2] = 300
0x100C      arr[3] = 400

?? 特點總結:

  • 每個元素都緊挨著上一個,偏移量是 sizeof(類型)

  • 編譯器知道數組是連續的,所以可以通過起始地址和偏移快速定位任意元素:
    arr[i] 等價于 *(arr + i)


?數組的聲明

在 C++ 中,聲明數組就是告訴編譯器我們要創建一個連續內存區域,用于存儲多個相同類型的數據項。聲明時必須指定類型和元素數量。?

1. int A[5];

含義:

  • 聲明一個整型數組 A,包含 5 個元素。

  • 未初始化,每個元素的值是未定義的垃圾值(在局部變量中)。

注意:

  • 在函數內部聲明的數組(局部數組)不會自動清零。

  • 在全局或靜態作用域中聲明的數組會被自動初始化為 0。

2. int A[5] = {2, 4, 6, 8, 10};

?含義:

  • 聲明一個大小為 5 的整型數組,并完全初始化所有元素。

  • A[0] = 2, A[1] = 4, ..., A[4] = 10

特點:

  • 初始化列表剛好填滿數組,無自動補零。

  • 所有元素值由你控制。

3. int A[5] = {2, 4};

含義:

  • 聲明一個大小為 5 的數組,只初始化前兩個元素。

  • 剩下的元素會被自動補零。

?結果是:

A[0] = 2  
A[1] = 4  
A[2] = 0  
A[3] = 0  
A[4] = 0

4. int A[5] = {0};

含義:

  • 聲明一個大小為 5 的數組,僅第一個元素初始化為 0。

  • 其余元素也會被自動補零。

  • 快速清零的技巧:用 {0} 初始化整個數組。

實際效果:

A[0] = 0  
A[1] = 0  
A[2] = 0  
A[3] = 0  
A[4] = 0

5. int A[] = {2, 4, 6, 8, 10};

含義:

  • 不指定大小,由初始化列表的元素數量自動推斷大小為 5。

  • 效果與 int A[5] = {2, 4, 6, 8, 10}; 相同。

編譯器推斷出:int A[5]; ? ? // ← 實際等價形式

?更簡潔,特別是在你明確初始化所有元素的情況下。

?


數組的訪問方式?

通過索引訪問數組元素(Index)

這是最常見、最直接的方式。

A[index]
  • index 是整數類型,從 0 開始。

  • 索引值必須在合法范圍內:0數組大小 - 1

用指針訪問數組元素?

數組名與指針的關系:

在大多數表達式中,數組名會自動退化為指向第一個元素的指針:

int A[5] = {1, 2, 3, 4, 5};
int* p = A;         // A 就是 &A[0]

此時:

  • pA 都指向數組開頭

  • 你可以用指針訪問元素

? 使用 *(pointer + index):?

int A[5] = {1, 2, 3, 4, 5};
int* p = A;cout << *(p + 0);   // 輸出 1
cout << *(p + 3);   // 輸出 4*(p + 2) = 100;     // 修改 A[2] 為 100

🟰 等價關系:

表達式含義
A[i]訪問數組第 i 個元素
*(A + i)使用數組名當指針
*(p + i)使用指針訪問數組元素
p[i]指針變量也支持 [] 下標運算(語法糖)

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

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

相關文章

視頻內存太大怎么壓縮變小一點?視頻壓縮的常用方法

視頻傳生活或者工作中很常見&#xff0c;如發送視頻郵件、在線視頻播放、視頻上傳下載等。未壓縮的大內存視頻文件傳輸時&#xff0c;不僅會消耗大量的網絡帶寬資源&#xff0c;還會使傳輸時間大幅增加。在網速有限的情況下&#xff0c;發送一個幾 GB 的未壓縮視頻可能需要數小…

性能測試包括哪些方面?要掌握哪些知識

性能測試是軟件測試中的一個重要方面&#xff0c;它主要關注軟件在不同條件下的穩定性、可靠性和性能表現。性能測試包括多個方面&#xff0c;需要掌握的知識也相對廣泛。以下是對性能測試包括的方面以及需要掌握的知識分析&#xff1a; 一、性能測試包括的方面 響應時間&…

windows的vscode無法通過ssh連接ubuntu的解決辦法

現象&#xff1a; 最近在windows本地通過vscode登錄ssh時發現不得勁&#xff0c;總是報錯無法與”192.168.1.129“建立連接&#xff0c;如下圖&#xff1a; 但是這種報錯以及在輸出端的信息并沒有提供具體錯誤原因&#xff0c;于是換poweshell來登錄&#xff0c;報錯如下圖&am…

第2章,[標簽 Win32] :Windows 的字符串函數

專欄導航 上一篇&#xff1a;第2章 &#xff1a;兼容 ASCII 字符與寬字符的 Windows 函數調用 回到目錄 下一篇&#xff1a;無 本節前言 在下面的文章鏈接里面&#xff0c;我們談到過&#xff0c;使用兼容版的字符串處理函數的知識。 第2章 &#xff1a;編寫兼容多字節字…

Java的SpringAI+Deepseek大模型實戰-會話記憶【三】

文章目錄 背景項目環境實現步驟第一步、定義會話存儲方式方式一、定義記憶存儲ChatMemory方式二、注入記憶存儲ChatMemory 第二步、配置會話記憶方式一、老版本實現方式二、新版本實現 第三步、添加會話ID 異常處理1、InMemoryChatMemory 無法解析 背景 前兩期搭建起大模型對話…

Python3完全新手小白的學習手冊 10 文件和異常

文章目錄 讀取文件讀取文件的全部內容 相對路徑和絕對路徑訪問文件中的各行使用文件的內容包含100萬位的大型文件圓周率值中包含你的生日嗎&#xff1f; 寫入文件寫入一行寫入多行 異常處理ZeroDivisionError異常使用try-except代碼塊else代碼塊處理FileNotFoundError異常分析文…

VC Spyglass:工具簡介

相關閱讀 VC Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828932.html?spm1001.2014.3001.5482 傳統上&#xff0c;基于仿真的動態驗證技術一直是功能驗證的核心方式。隨著現代SoC設計日益復雜&#xff0c;靜態驗證技術的引入變得愈發重要。 Synopsys的 VC Sp…

AWS RDS Aurora全局數據庫轉區域數據庫實戰指南:無縫遷移零停機

Aurora全局數據庫是AWS提供的跨區域高可用解決方案,但在某些場景下,我們需要將其轉換為普通區域數據庫。本文將詳細介紹這一轉換過程,并分享關鍵技術要點和實戰經驗。 一、全局數據庫與區域數據庫概述 AWS RDS Aurora全局數據庫是一種跨區域部署的數據庫架構,主要用于災備…

C++之路:函數重載與運算符重載

目錄 函數重載運算符重載C運算符重載范圍對照表注意事項 運算符重載語法全局運算符重載類內運算符重載下面以一個一元運算符為例&#xff0c;介紹特性1&#xff1a;下面介紹特性3&#xff1a;&#xff08;必須類內重載的運算符?&#xff09; 函數重載 函數重載是指同一個作用域…

七、SpringCloud 項目遷移至 K8s

七、SpringCloud 項目遷移至 K8s 文章目錄 七、SpringCloud 項目遷移至 K8s1、環境準備1.1 集群規劃1.2 SpringCloud 項目架構及遷移需求分析 2、遷移 Eureka 集群2.1 構建及容器化2.2 部署至 K8s2.3 創建通信Service 3、遷移網關服務3.1 構建及容器化3.2 部署至 K8s3.3 創建Se…

通過具有一致性嵌入的大語言模型實現端到端乳腺癌放射治療計劃制定|文獻速遞-最新論文分享

Title 題目 End-to-end breast cancer radiotherapy planning via LMMs with consistency embedding 通過具有一致性嵌入的大語言模型實現端到端乳腺癌放射治療計劃制定 01 文獻速遞介紹 近年來&#xff0c;受大型語言模型&#xff08;LLM&#xff09;啟發的新一代人工智…

MCP Chart Server服務本地部署案例

一、MCP Chart Server介紹 MCP Chart Server是一個專業的圖表生成服務&#xff0c;支持多種圖表類型&#xff0c;適用于數據可視化和分析。 MCP Chart Server是一種用于生成和呈現圖表的服務器端軟件。它提供了一個簡單而強大的方式&#xff0c;讓開發人員和系統管理員可以輕…

復合型浪涌保護器五大核心技術重構電氣防護體系

開篇&#xff1a;從傳統防護到智能守護的技術跨越 在電氣設備面臨浪涌威脅的防護場景中&#xff0c;浪涌保護器&#xff08;SPD&#xff09;始終扮演著關鍵角色。面對傳統SPD在漏電流、續流等方面的技術局限&#xff0c;行業領先企業通過技術整合開發出復合型SPD&#xff0c;以…

c# 詳細分析Task.sleep和Thread.sleep 的區別、使用場景和應用示例

文章目錄 Task.Delay vs Thread.Sleep 詳細分析與使用場景核心區別詳細分析Thread.SleepTask.Delay 性能考量綜合示例高級用法組合延遲與超時實現指數退避重試 總結建議 Task.Delay vs Thread.Sleep 詳細分析與使用場景 核心區別 Task.Delay 和 Thread.Sleep 都用于在代碼中引…

Vue 3 中的 `h` 函數詳解

h 函數是 Vue 3 中用于創建**虛擬 DOM 節點(VNode)**的核心函數&#xff0c;它是 Vue 渲染系統的基石。下面我將全面解釋它的作用、用法和重要性。 1. h 函數的基本概念 h 是 createVNode 的簡稱&#xff0c;來源于"hyperscript"的縮寫傳統。它的主要作用是&#x…

SoapCore 全面介紹:在 .NET Core 中實現 SOAP 服務的現代解決方案

一、什么是 SoapCore&#xff1f; 在現代微服務和 REST API 成為主流的今天&#xff0c;SOAP&#xff08;Simple Object Access Protocol&#xff09;看似已經被邊緣化&#xff0c;但在許多企業和政務系統中&#xff0c;SOAP 仍然是 重要的通信協議。特別是在金融、保險、醫療…

JDBC工具類和SQL 注入問題

在軟件開發中&#xff0c;數據庫安全與高效訪問一直是關鍵課題。本文將圍繞 SQL 注入問題的原理、解決方案&#xff0c;以及 JDBC 開發中的工具類演進和連接池技術展開探討&#xff0c;結合實際代碼示例&#xff0c;為開發者提供清晰的技術實踐指南。 SQL 注入問題的核心原理與…

2022年SEVC SCI2區,分數階蟻群算法FACA:一種基于分數階長期記憶的合作學習方法,深度解析+性能實測

目錄 1.摘要2.分數階微積分基礎知識3.分數階蟻群算法FACA4.分數階蟻群算法FACA數學證明與分析5.結果展示6.參考文獻7.代碼獲取8.算法輔導應用定制讀者交流 1.摘要 本文提出了一種新穎分數階蟻群算法&#xff08;Fractional-Order Ant Colony Algorithm&#xff0c; FACA&#…

java+vue+SpringBoo數字科技風險報告管理系統(程序+數據庫+報告+部署教程+答辯指導)

源代碼數據庫LW文檔&#xff08;1萬字以上&#xff09;開題報告答辯稿ppt部署教程代碼講解代碼時間修改工具 技術實現 開發語言&#xff1a;后端&#xff1a;Java 前端&#xff1a;vue框架&#xff1a;springboot數據庫&#xff1a;mysql 開發工具 JDK版本&#xff1a;JDK1.…

YOLOv12_ultralytics-8.3.145_2025_5_27部分代碼閱讀筆記-augment.py

augment.py ultralytics\data\augment.py 目錄 augment.py 1.所需的庫和模塊 2.class BaseTransform: 3.class Compose: 4.class BaseMixTransform: 5.class CutMix(BaseMixTransform): 6.class CopyPaste(BaseMixTransform): 7.def v8_transforms(dataset, img…