最新c語言數(shù)組的指針 c語言數(shù)組指針的用法實用

格式:DOC 上傳日期:2023-04-27 20:40:17
最新c語言數(shù)組的指針 c語言數(shù)組指針的用法實用
時間:2023-04-27 20:40:17     小編:zdfb

在日常的學(xué)習(xí)、工作、生活中,肯定對各類范文都很熟悉吧。相信許多人會覺得范文很難寫?以下是我為大家搜集的優(yōu)質(zhì)范文,僅供參考,一起來看看吧

c語言數(shù)組的指針 c語言數(shù)組指針的用法篇一

由于數(shù)據(jù)的表現(xiàn)形式多種多樣,還有字符型和其它的數(shù)值類型,因此僅有基本數(shù)據(jù)類型是不夠的。是否可以通過基本數(shù)據(jù)類型的組合抽象構(gòu)造其它的數(shù)據(jù)類型呢?下面是小編為大家?guī)淼腸語言數(shù)組與指針詳解的知識,歡迎閱讀。

我們知道,一個基本數(shù)據(jù)類型的變量只能存儲一個數(shù)據(jù),比如:

int data = 0x64;

如果需要存儲一組int型數(shù)據(jù)呢?比如,1、2、3,則至少需要3個變量data0、data1、data2。比如:

int data0 = 1, data1 = 2, data2 =3;

由于數(shù)據(jù)的表現(xiàn)形式多種多樣,還有字符型和其它的數(shù)值類型,因此僅有基本數(shù)據(jù)類型是不夠的。是否可以通過基本數(shù)據(jù)類型的組合抽象構(gòu)造其它的數(shù)據(jù)類型呢?答案是可以的,構(gòu)造數(shù)據(jù)類型數(shù)組就是這樣產(chǎn)生的。

從概念的視角來看,int型整數(shù)1、2和3都是相同的數(shù)據(jù)類型,data0、data1和data2三個變量的共性是data,其差異性是下標(biāo)不一樣。因此可以將data0、data1和data2抽象為一個名字,然后用下標(biāo)區(qū)分這些變量的集合——data[0]、data[1]和data[2]。如果有以下聲明:

intdata[3]; //解讀為data是int數(shù)組(元素個數(shù)3)

那么data[3]就成了存放3個int型數(shù)據(jù)1、2、3的data[0]、data[1]和data[2]所組成的數(shù)組,即可分別對data[0]、data[1]和data[2]賦值:

data[0] = 1, data[1] =2, data[2] = 3;

當(dāng)然,也可以按照以下方式聲明一個數(shù)組并進行初始化:

intdata[3] = {1, 2, 3};

通常將data稱為數(shù)組(變量)名,data[0]、data[1]和data[2]被稱為變量。因而可以說,數(shù)組是將相同類型數(shù)據(jù)的若干變量按有序的形式組織起來,用一個名字命名,然后用下標(biāo)區(qū)分這些變量的集合。

由于數(shù)組是建立在其它類型的基礎(chǔ)上,因此c將數(shù)組看作構(gòu)造類型,在聲明數(shù)組時必須說明其元素的類型。比如,int類型的數(shù)組、float類型的數(shù)組或其它類型的數(shù)組。而其它類型也可以是數(shù)組類型,在這種情況下,創(chuàng)建的是數(shù)組類型的數(shù)組,簡稱數(shù)組的數(shù)組。

在這里,定義了一個名為data的數(shù)組類型變量,它是由存放3個int型數(shù)據(jù)1、2、3的變量data[0]、data[1]和data[2]組成的。通常又將數(shù)組的各個變量稱為數(shù)組的元素,而數(shù)組的元素是按照順序編號的,這些元素的編號又稱為數(shù)組元素的下標(biāo)。

由于有了下標(biāo),因此數(shù)組元素在內(nèi)存中的位置就被唯一確定下來了。下標(biāo)總是從0開始的,最后一個元素的下標(biāo)為元素的個數(shù)減1(即2),data[0]叫第1個元素,data[1]叫第2個元素,data[2]叫第3個元素,也就意味著所有的元素在內(nèi)存中都是連續(xù)存儲的。

直觀上,數(shù)組是由下標(biāo)(或稱為索引)和值所組成的序?qū)?,對于每個有定義的下標(biāo)都存在一個與其關(guān)聯(lián)的值,在數(shù)學(xué)上稱為映射。除了創(chuàng)建新數(shù)組外,大多數(shù)語言對數(shù)組只提供兩種標(biāo)準(zhǔn)操作:一個操作是檢索一個值,另一個操作是存儲一個值。

函數(shù)create(data, size)創(chuàng)建一個新的具有適當(dāng)大小的空數(shù)組,初始時數(shù)組的每一項都沒有定義。retrieve操作接受一個數(shù)組data和一個下標(biāo)index,如果下標(biāo)合法,則該操作返回與下標(biāo)關(guān)聯(lián)的值,否則產(chǎn)生一個錯誤。store操作接受一個數(shù)組data、一個下標(biāo)index和一個項item的集合,即項是value值的集合,有時也將值(value)稱為項(item),返回在原來數(shù)組中增加新的序?qū)蟮臄?shù)組。

顯然,int系的任何常量表達式都可以作為數(shù)組元素的下標(biāo)。比如:

int array[3+5]; // 合法

int array['a']; //表示int array[97];

上述定義之所以合法,因為表示元素個數(shù)的常量表達式在編譯時就具有確定的意義,與變量的定義一樣明確地分配了固定大小的空間。

雖然使用符號常量增強了數(shù)組的靈活性,但如果定義采用了以下的形式:

int n = 5;

int array[n]; //非法

因為標(biāo)準(zhǔn)c認(rèn)為數(shù)組元素的個數(shù)n不是常量,雖然編譯器似乎已經(jīng)“看到”了n的值,但intarray[n]要在運行時才能讀取變量n的值,所以在編譯期無法確定其空間大小。使用符號常量定義數(shù)組長度的正確形式如下:

#define n 10

int array[n];

即可根據(jù)實際的需要修改常量n的值。

由于數(shù)組元素下標(biāo)的有效范圍為0~n-1,因此data[n]是不存在的,但c語言并不檢查下標(biāo)是否越界。如果訪問了數(shù)組末端之后的元素,訪問的就是與數(shù)組不相關(guān)的內(nèi)存。它不是數(shù)組的一部分,使用它肯定會出問題。c為何允許這種情況發(fā)生呢?這要歸功于c信任程序員,因為不檢查越界可以使運行速度更快,所以編譯器沒有必要檢查所有的下標(biāo)錯誤。因為在程序運行之前,數(shù)組的下標(biāo)可能尚未確定,所以為了安全起見,編譯器必須在運行時添加額外代碼檢查數(shù)組的每個下標(biāo)值,但這樣會降低程序的運行速度。c相信程序員能編寫正確的代碼,這樣的程序運行速度更快。但并不是所有的程序員都能做到這一點,越界恰恰是初學(xué)者最容易犯的錯誤,因此要特別注意下標(biāo)的范圍不能超出合理的界限。

當(dāng)將變量data[0]、data[1]和data[2]作為&的操作數(shù)時,&data[0]是指向變量data[0]的指針,&data[1]是指向變量data[1]的指針,&data[2]是指向變量data[2]的指針。data[0]、data[1]和data[2]變量的類型為int,&data[0]、&data[1]和&data[2]指針的類型為int *const,即指向常量的指針,簡稱常量指針,其指向的值不可修改。比如:

int a;

int * const ptr = &a;

ptr = null; //試圖修改,則編譯報警

&a = null; //試圖修改,則編譯報警

同理,&data是指向變量data的指針,那么data是什么類型?

按照聲明變量的規(guī)約,將標(biāo)識符data取出后,剩下的“int [3]”就是data的類型,通常將其解釋為由3個int組成的數(shù)組類型,簡稱數(shù)組類型。其目的是告訴編譯器需要分配多少內(nèi)存?3個元素的整數(shù)數(shù)組,data類型測試程序詳見程序清單 1.20。

程序清單 1.20 data類型測試程序

1 #include

2

3 void f(int x);

4 int main(int argc, char *argv[])

5 {

6 int data[3];

7 f(data);

8 return 0;

10 }

通過編譯器提示的警告,“funtion: 'int' differ in levels ofindirection from 'int [3]'”,說明數(shù)組變量data的類型為不是int而是int [3]數(shù)組類型。由于在設(shè)計c語言時,過多地考慮了開發(fā)編譯器的便利。雖然設(shè)計編譯器更方便了,卻因為概念的模糊給初學(xué)者造成了理解上的困難。實際上數(shù)組應(yīng)該這樣定義:

int[3] data;

即int是與[3]結(jié)合的。&data到底是什么類型?

當(dāng)data作為&的操作數(shù)時,則&data是指向data的指針。由于data的類型為int [3],因此&data是指向“int [3]數(shù)組類型”變量data的指針,簡稱數(shù)組指針。其類型為int (*)[3],即指向int [2]的指針類型。為何要用“()”將“*”括起來?

如果不用括號將星號括起來,那么“int (*)[3]”就變成了“int *[3]”,而int*[3]類型名為指向int的指針的數(shù)組(元素個數(shù)3)類型,這是設(shè)計編譯器時約定的語法規(guī)則。

&data的類型到底是不是“int (*)[3]”?其驗證程序范例詳見程序清單 1.21。

程序清單 1.21 &data類型測試程序

1 #include

2 int main(int argc, char *argv[])

3 {

4 int data[3];

5 int b = &data;

6 return 0;

7 }

通過編譯器提示的警告,“'int' differ in levels ofindirection from 'int (*)[3]'”,說明&data的類型為int (*)[3]。

(4)sizeof(data)

將如何尋找相應(yīng)的數(shù)組元素呢?常用的方法是通過“數(shù)組的基地址+偏移量”算出數(shù)組元素的地址。在這里,第一個元素&data[0]的地址稱為基地址,其偏移量就是下標(biāo)值和每個元素的大小sizeof(int)相乘。假設(shè)數(shù)組元素&data[0] 的地址為a,且在內(nèi)存中的實際地址為0x22ff74,那么&data[1]的值為:當(dāng)data作為sizeof的操作數(shù)時,其返回的是整個數(shù)組的長度。在這里,sizeof(data)的大小為12,即3個元素占用的.字節(jié)數(shù)為4×3=12,系統(tǒng)會認(rèn)為&data+1中的“1”,偏移了一個數(shù)組的大小,因此&data +1是下一個未知的存儲空間的地址(即越界)。在小端模式下,數(shù)組在內(nèi)存中的存儲方式詳見圖 1.10。

a + 1×sizeof(int) = (unsignedint)data + 4 = 0x22ff74 + 4 = 0x22ff78

&data[2]的值為:

a + 2×sizeof(int) = (unsigned int)data+ 8 = 0x22ff74 + 8 = 0x22ff7c

實際上,當(dāng)在c語言中書寫data[i]時,c將它翻譯為一個指向int的指針。data是指向data[0]的指針,data+i是指向data[i]的,因此不管data數(shù)組是什么類型,總有data+i等于data[i],于是*(data+i)等于data[i],其相應(yīng)的測試范例程序詳見程序清單 1.22。

程序清單 1.22變量的地址測試程序

1 #include

2 int main(int argc, char *argv[])

3 {

4 int data[3]= {1, 2, 3};

5 printf("%x, %x, %x, %x, %x",&data[0], &data[1], &data[2], &data, &data+1);

6 return0;

7 }

實踐證明,雖然&data[0]與&data的類型不一樣,但它們的值相等。同時也可以看出,數(shù)組的元素是連續(xù)存儲的。如果將數(shù)組變量占用內(nèi)存的大小除以數(shù)組變量中一個元素所占用空間的大小,便可得到數(shù)組元素的個數(shù)。即:

int numdata = sizeof(data) / sizeof(data[0]);

當(dāng)然,也可以使用宏定義計算數(shù)組元素的個數(shù):

#define nelems(data)(sizeof(data) / sizeof(data[0]))

當(dāng)數(shù)組作為函數(shù)的參數(shù)時,c語言函數(shù)的所有參數(shù)必須在函數(shù)內(nèi)部聲明。但是,由于在函數(shù)內(nèi)部并沒有給數(shù)組分配新的存儲空間,因此一維數(shù)組的容量只在主程序中定義。顯然,如果函數(shù)需要得到一維數(shù)組的大小,則必須將它以函數(shù)參數(shù)的形式傳入函數(shù)中,或?qū)⑺鳛槿肿兞吭L問。

標(biāo)準(zhǔn)c規(guī)定:除了“在聲明中”或“當(dāng)一個數(shù)組名是sizeof或&的操作數(shù)”之外,只要數(shù)組名出現(xiàn)在表達式中,這編譯器總是將數(shù)組名解釋為指向該數(shù)組的第一個元素的指針。

雖然data在表達式中解讀為指向該數(shù)組首元素data[0]的指針,但實際上data被解讀為&data[0]或等價于“*data==data[0]”,因此data與&data[0]的值相等,且它們的類型都是int *const,即一個數(shù)組名是一個不可修改的常量指針(左值)。

根據(jù)指針運算規(guī)則,當(dāng)將一個整型變量i和一個數(shù)組名相加時,其結(jié)果是指向數(shù)組第i個元素的指針,即data+index==&data[index],*(data+index)==data[index],因此習(xí)慣性地將:

int * ptr = &data[0];

寫成下面這樣的形式:

int *ptr = data;

由于data的類型是不可修改的常量指針int*const,因此任何試圖使數(shù)組名指向其它地方的行為都是錯誤的。比如:

data ++; //錯誤

雖然data有地址,但其類型為int *const,因此不能對data++賦值,同樣也不能反過來給data賦值。比如:

data = ptr;

類型地,象下面這樣的表達式也是非法的:

intdata[3];

data= {1, 2, 3};

但可以將data復(fù)制給指針變量ptr,通過改變指針變量達到目的。比如:

#define n 10

int data[n];

int *ptr;

for(ptr = data; ptr < data + n; ptr ++)

sum+= *ptr;

for語句中的條件p

int sum = 0;

while(ptr < data +n)

sum += *ptr++;

其中,*ptr++等價于*(ptr++),它的含義為自增前表達式的值是*ptr,即ptr當(dāng)前指向的對象,以后再自增ptr。

s("content_relate");

【c語言數(shù)組與指針詳解】相關(guān)文章:

c語言指針數(shù)組的概念

10-22

c語言中指針與數(shù)組的區(qū)別

10-05

c語言指針用法詳解

10-19

c語言指針函數(shù)和函數(shù)指針詳解

06-10

c語言指針和數(shù)組基礎(chǔ)知識

10-04

c語言之復(fù)雜指針詳解

10-26

c語言指針和數(shù)組的學(xué)習(xí)方法

10-24

c++ this指針詳解

10-01

c語言指針教學(xué)

11-05

【本文地址:http://gzsthw.cn/zuowen/2734961.html】

全文閱讀已結(jié)束,如果需要下載本文請點擊

下載此文檔