數(shù)組和指針的本質(zhì)差異在于內(nèi)存訪問方式和語(yǔ)義層面。1.數(shù)組是靜態(tài)分配的連續(xù)內(nèi)存塊,不能被重新賦值,位置固定;2.指針是保存地址的變量,可指向不同內(nèi)存區(qū)域,支持動(dòng)態(tài)內(nèi)存分配;3.數(shù)組訪問通過(guò)基地址+偏移量實(shí)現(xiàn),效率更高,而指針訪問需先取地址再訪問內(nèi)容,屬于間接尋址;4.數(shù)組傳參時(shí)會(huì)退化為指針,導(dǎo)致無(wú)法直接獲取數(shù)組大小,需額外傳遞長(zhǎng)度參數(shù)。理解這些區(qū)別有助于編寫更高效、安全的c++++代碼。
在c++中,數(shù)組和指針看起來(lái)很像,尤其是在某些用法上可以互換。但它們的本質(zhì)差異在于內(nèi)存訪問方式和語(yǔ)義層面的不同。理解這些差異,能幫助你寫出更高效、安全的代碼。
數(shù)組是靜態(tài)分配的連續(xù)內(nèi)存塊
當(dāng)你聲明一個(gè)數(shù)組時(shí),比如:
int arr[5] = {1, 2, 3, 4, 5};
編譯器會(huì)在棧上為這5個(gè)整型元素分配連續(xù)的內(nèi)存空間,并且這塊內(nèi)存的大小是固定的。數(shù)組名 arr 實(shí)際上代表的是這段內(nèi)存的起始地址,但它不是一個(gè)變量,不能被重新賦值。
立即學(xué)習(xí)“C++免費(fèi)學(xué)習(xí)筆記(深入)”;
也就是說(shuō),你不能寫成:
int arr2[5]; arr = arr2; // 錯(cuò)誤!數(shù)組名不能作為左值
數(shù)組一旦定義,它的位置就固定了,不能改變指向。
指針是一個(gè)變量,保存地址
相比之下,指針是一個(gè)變量,它保存的是某個(gè)內(nèi)存地址。你可以讓它指向不同的地方:
int* p = arr; // p 指向 arr 的第一個(gè)元素 p = &arr[2]; // 現(xiàn)在 p 指向第三個(gè)元素
甚至你可以動(dòng)態(tài)分配內(nèi)存給指針使用:
int* p = new int[10]; // 在堆上分配10個(gè)整數(shù)的空間 // 使用完記得釋放 delete[] p;
指針靈活但也容易出錯(cuò),比如忘記釋放內(nèi)存導(dǎo)致泄漏,或者訪問非法地址造成崩潰。
內(nèi)存訪問方式:數(shù)組更“直接”,指針更“間接”
數(shù)組訪問元素是通過(guò)基地址 + 偏移量的方式進(jìn)行的,這個(gè)過(guò)程在編譯期就能確定,效率很高。例如:
arr[2]
等價(jià)于:
*(arr + 2)
而指針訪問元素雖然形式一樣:
p[2]
但背后是先取指針變量的值(也就是地址),再去訪問那個(gè)地址的內(nèi)容,屬于間接尋址。這種靈活性是以犧牲一點(diǎn)性能為代價(jià)的(雖然現(xiàn)代編譯器優(yōu)化后差別不大)。
函數(shù)傳參時(shí)的行為不同
這一點(diǎn)特別重要。當(dāng)你把數(shù)組作為參數(shù)傳遞給函數(shù)時(shí),它會(huì)退化為指針:
void func(int arr[]) { // 這里的 arr 實(shí)際上是個(gè) int* }
所以在這個(gè)函數(shù)里,sizeof(arr) 得到的是指針的大小,而不是整個(gè)數(shù)組的大小。如果你需要知道數(shù)組長(zhǎng)度,必須額外傳一個(gè)參數(shù)進(jìn)去:
void func(int* arr, int size) { // 使用 arr 和 size }
這也是為什么很多新手在處理數(shù)組時(shí)容易犯錯(cuò)的地方。
基本上就這些。數(shù)組和指針雖然在語(yǔ)法上有時(shí)可以混用,但在底層機(jī)制和行為上有本質(zhì)區(qū)別。理解它們的內(nèi)存訪問方式,有助于你在實(shí)際編程中做出更合適的選擇。