成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C語言核心之?dāng)?shù)組和指針詳解

開發(fā) 后端
在C語言中,函數(shù)雖然不是變量,但可以定義指向函數(shù)的指針。這種類型的指針可以被賦值,存放在數(shù)組中,傳遞給函數(shù)以及作為函數(shù)的返回值等。

指針

[[177918]]

相信大家對下面的代碼不陌生:

  1. int i=2;                                            
  2. int *p;                                             
  3. p=&i; 

這是最簡單的指針應(yīng)用,也是最基本的用法。再來熟悉一下什么是指針:首先指針是一個變量,它保存的并不是平常的數(shù)據(jù),而是變量的地址。如上代碼,指針p中保存的是整型變量i的地址信息。

接下來看如何定義一個指針,既然指針也是一個變量,那么它的定義也和其它變量一樣定義:如:int p;是間接尋址或間接引用運(yùn)算符。上例中我們還看到了一個特別的運(yùn)算符&,它是一個取地址運(yùn)算符(在其他合適場合&也是按位運(yùn)算運(yùn)算符,&&為取交集運(yùn)算符)。

在上面的指針定義中,我們看到了定義的是一個整型指針,難道指針還有類型嗎?答案是肯定的,指針只能指向某種特定類型的對象,也就是說,每個指針都必須指向某種特定的數(shù)據(jù)類型(***的例外:指向void類型的指針可以存放指向任何類型的指針,但它不能間接引用其自身。)。比如,int 類型的指針絕對不能指向char 類型的變量。

下面我們給出一個完整的例子來說明指針的簡單應(yīng)用:

  1. #include<stdio.h> 
  2. void main() 
  3.     int a,b,c,*p; 
  4.     a=1; 
  5.     b=3; 
  6.     p=&a; 
  7.     b=*p+1; 
  8.     c=*(p+1); 
  9.     printf("%d %d %d %d /n",a,b,c,*p+3); 

運(yùn)行結(jié)果為: 1 2 -858993460 4

這是個完整的例子,可以自己在機(jī)器上調(diào)試一下,現(xiàn)在很多人用的都是微軟的Visual Studio 開發(fā)環(huán)境,有人就不知道在該開發(fā)環(huán)境中怎么寫C程序以及調(diào)試C程序,具體境況可以參考附錄。

在上面例子中,看到了這樣兩個表達(dá)式b=p+1;和c=(p+1);前者的意思是p所指的地址里的內(nèi)容加1再賦給b,相當(dāng)于b=a+1;,后者是p所指的地址加1再把(p+1)所指的地址賦給c,當(dāng)然我們不知道p的下一個地址里放的是什么,所以輸出了一個隨機(jī)值(這樣的操作時很危險的,切記不要使用不確定的內(nèi)存地址)。

數(shù)組

數(shù)組大家應(yīng)該都很熟悉了,用途非常廣泛。

  1. int a[4]={2,4,5,9}; 

此語句定義一個4個空間大小的整型數(shù)組a并為它進(jìn)行了初始化。

數(shù)組的基礎(chǔ)知識可以參考其他相應(yīng)的教材,我們在這主要討論指針和數(shù)組的結(jié)合應(yīng)用。

我們再來看個完整的例子:

  1. #include<stdio.h> 
  2. void main() 
  3.     int a[4]={2,4,5,9}; 
  4.     int *p; 
  5.     p=a; 
  6.     *p=*p++; 
  7.     printf("%d %d %d/n",*p,*p+6,*(p+1)); 

運(yùn)行結(jié)果:4 10 5

分析:語句p=a;表示把數(shù)組a的第0個元素的地址賦給指針p,數(shù)組名a代表的是數(shù)組a的第0個元素的地址。

a[i]表示數(shù)組a的第i個元素,如果定義一個指針p,那么語句p=&a[0];表示可以將指針p指向數(shù)組a的第0個元素,也就是說p的值為數(shù)組元素a[0]的地址。那么(p+1)引用的是數(shù)組元素a[1]的內(nèi)容,p+i是數(shù)組元素a[i]的地址,(p+i)引用的是數(shù)組元素a[i]的內(nèi)容。對數(shù)組元素a[i]的引用也可以寫成(a+i)。可以得出結(jié)論:&a[i]與a+i的含義相同,p[i]與(p+i)也是等價的。

雖然數(shù)組和指針有這么多通用的地方,但我們必須記住,數(shù)組名和指針之間有一個不同之處。指針是一個變量,因此語句p=a和p++都是合法的。但數(shù)組名不是變量,因此,類似于a=p和a++形式的語句是非法的。

下面來看一個我們常用的函數(shù)strlen(char *s):

  1. int strlen(char *s) 
  2.     int n; 
  3.     for(n=0;*s!='/0';s++) 
  4.           n++; 
  5.     return n; 

因?yàn)閟是一個指針,所以對其執(zhí)行自增運(yùn)算是合法的。執(zhí)行s++運(yùn)算不會影響到strlen函數(shù)的調(diào)用者中的字符串,它僅對該指針在strlen函數(shù)中的私有副本進(jìn)行自增運(yùn)算。在函數(shù)定義中,形式參數(shù)char s[]和char *s是等價的。

我們再來看一下地址算術(shù)運(yùn)算:如果p是一個指向數(shù)組中某個元素的指針,那么p++將對p進(jìn)行自增運(yùn)算并指向下一個元素,而p+=i將對p進(jìn)行加i的增量運(yùn)算,使其指向指針p當(dāng)前所指向元素之后的第i個元素。同其他類型的變量一樣,指針也可以進(jìn)行初始化。通常,對指針有意義的初始化值只能是0或者是表示地址的表達(dá)式,對后者來說,表達(dá)式所表達(dá)的地址必須是在此之前已定義的具有適當(dāng)類型的數(shù)據(jù)的地址。任何指針與0進(jìn)行相等或者不相等的比較運(yùn)算都有意義。但是指向不同數(shù)組的元素的指針之間的算術(shù)或比較運(yùn)算沒有意義。指針還可以和整數(shù)進(jìn)行相加或相減運(yùn)算。如p+n表示指針p當(dāng)前指向的對象之后第n個對象的地址。無論指針p指向的對象是何種類型,上述結(jié)論都成立。在計算p+n時,n將根據(jù)p指向的對象的長度按比例縮放,而p指向的對象的長度則取決于p的聲明。例如,如果int類型占4個字節(jié)的存儲空間,那么在int類型的計算中對應(yīng)的n將按4的倍數(shù)來計算。

指針的減法運(yùn)算也是有意義的,如果p和q指向相同數(shù)組中的元素,且p<q,那么q-p+1就是位于p和q指向的元素之間的元素的數(shù)目。我們來看一下strlen(char *s)的另一個版本:

  1. int strlen(char *s) 
  2.    char *p=s; 
  3.    while(*p!='/0'
  4.           p++; 
  5.    return p-s; 

程序中,p被初始化為指向s,即指向該字符串的***個字符,while循環(huán)語句將依次檢查字符串中的每個字符,直到遇到標(biāo)識字符數(shù)組結(jié)尾的字符’/0’為止。由于p是指向字符的指針,所以每執(zhí)行以此p++,p就將指向下一個字符的地址,p-s則表示已經(jīng)檢查過的字符數(shù),即字符串長度。

總結(jié):有效的指針運(yùn)算包括相同類型指針之間的賦值運(yùn)算;指針和整數(shù)之間的加減運(yùn)算;指向相同數(shù)組中元素的兩個指針間的減法或比較運(yùn)算;將指針賦值為0或指針與0之間的比較運(yùn)算。其他所有形式的指針運(yùn)算都是非法的。

再來看兩條語句:

char  a[]=”I  am  a  boy”;  char *p=”I  am  a  boy”;

a是一個僅僅足以存放初始化字符串以及空字符’/0’的一維數(shù)組。數(shù)組中的單個字符可以進(jìn)行修改,但a始終指向同一個存儲位置。而p是一個指針,其初值指向一個字符串常量,之后它可以被修改以指向其他地址,但如果試圖修改字符串的內(nèi)容,結(jié)果是沒有定義的。

為了更容易理解數(shù)組和指針的關(guān)系,我們再來看一個函數(shù):

  1. void strcpy(char *s,char *t) 
  2.    int i; 
  3.    i=0; 
  4.    while((s[i]=t[i])!='/0'
  5.           i++; 

因?yàn)閰?shù)是通過值傳遞的,所以在strcpy函數(shù)中可以以任何方式使用參數(shù)s和t。

下面是指針實(shí)現(xiàn)的幾個版本:

  1. void strcpy(char *s,char *t) 
  2.    while((*s=*t)!='/0'){ 
  3.           s++; 
  4.           t++; 
  5.    } 

最簡版本:

  1. void strcpy(char *s,char *t) 
  2.    while(*s++=*t++) 
  3.           ; 

這里,s和t的自增運(yùn)算放到了循環(huán)的測試部分中。表達(dá)式*t++的值是執(zhí)行自增運(yùn)算之前t所指向的字符。后綴運(yùn)算符++表示在讀取該字符之后才改變t的值。同樣,在s執(zhí)行自增運(yùn)算之前,字符就被存儲到了指針s指向的舊位置。上面的版本中表達(dá)式同’/0’的比較是多余的,因?yàn)橹恍枰袛啾磉_(dá)式的值是否為0即可。

指針數(shù)組和指向指針的指針

這兩個詞次聽起來挺新穎的,到底是什么意思呢?

由于指針本身也是變量,所以它們也可以像其他變量一樣存儲在數(shù)組中。這一點(diǎn)很容易理解。

  1. #include<stdio.h> 
  2. #include<string.h> 
  3. void main() 
  4.    int i; 
  5.    char b[]={"wustrive_2008"}; char *a[1]; *a=b; for(i=0;i<strlen(b);i++) printf("%c",*(a[0]+i)); printf("/n"); 

運(yùn)行結(jié)果:wustrive_2008

這里庫函數(shù)strlen,strlen為string類的標(biāo)準(zhǔn)庫函數(shù),所以要包含#include。

下面我們來自己寫一個strlen函數(shù),我們把上面的例子該成這樣:

  1. #include<stdio.h> 
  2. int strlen(char *s) 
  3.    char *p=s; 
  4.    while(*p!='/0'
  5.           p++; 
  6.    return p-s; 
  7. void main() 
  8.    int i; 
  9.    char b[]={"wustrive_2008"}; char *a[1]; *a=b; for(i=0;i<strlen(b);i++) printf("%c",*(a[0]+i)); printf("/n"); 

這個運(yùn)行結(jié)果和上個例子一樣,不一樣的只是我們自己實(shí)現(xiàn)了strlen函數(shù),我們再編程時使用的庫函數(shù),都是語言的開發(fā)者或者系統(tǒng)為我們寫好了的函數(shù),其實(shí)我們也可以自己寫。

這個例子很好的演示了指針數(shù)組的用法,指針數(shù)組a的值a[1]是一個指針,指向字符數(shù)組***個字符。

指針的指針也很好理解,就是一個指針里放的是另一個指針的地址,而另一個指針可能指向一個變量的地址,還可能指向另一個指針。

指針和多維數(shù)組

看兩個定義語句:int a[5][10]; int *b[5];

從語法角度講,a[3][4]和b[3][4]都是對一個int對象的合法引用。但a是一個真正的二維數(shù)組,它分配了50個int類型長度的存儲空間。但b定義僅僅分配了5個指針,并且沒有初始化,它們必須進(jìn)行顯示的初始化,假設(shè)b的每個元素都指向一個有10個元素的數(shù)組,那么編譯器就要為它分配50個int類型長度的存儲空間以及5個指針存儲空間。指針數(shù)組的一個重要優(yōu)點(diǎn)在于,數(shù)組的每一行長度可以不同,也就是說,b的每個元素不必都指向一個有10個元素的向量。

指向函數(shù)的指針:

在C語言中,函數(shù)雖然不是變量,但可以定義指向函數(shù)的指針。這種類型的指針可以被賦值,存放在數(shù)組中,傳遞給函數(shù)以及作為函數(shù)的返回值等。

如果下面的語句為一個函數(shù)的參數(shù),表示什么意思:

  1. int (p)(void ,void *) 

它表明p是一個指向函數(shù)的指針,該函數(shù)具有兩個void類型的參數(shù),其返回值類型為int。語句if((p)(v[i],v[left])<0)中,p的使用和其聲明是一致的,p是一個指向函數(shù)的指針,p代表一個函數(shù)。如果寫成這樣:int p(void ,void )則表明p是一個函數(shù),該函數(shù)返回一個int類型的指針。

下面來看兩個聲明:

int  *f();      //f是一個函數(shù),它返回一個指向int類型的指針
int   (*pf)();     //pf是一個指向函數(shù)的指針,該函數(shù)返回一個int類型的對象。

 

責(zé)任編輯:張燕妮 來源: wustrive
相關(guān)推薦

2011-07-15 01:38:56

C++this指針

2014-04-01 10:11:33

C語言指針

2021-08-06 13:48:53

C語言野指針內(nèi)存

2011-07-15 01:20:58

C指針函數(shù)函數(shù)指針

2022-07-14 16:35:11

C語言編程語言

2009-09-16 09:00:15

C#數(shù)組C#指針

2009-09-27 11:14:09

C#數(shù)組

2021-12-21 15:31:10

C++語言指針

2021-02-24 15:05:32

C語言數(shù)組代碼

2015-12-24 09:48:40

JavaScriptthis指針深

2011-07-13 16:14:53

C++引用指針

2021-01-13 06:58:35

C語言函數(shù)指針

2023-09-14 12:35:28

寄存器

2021-07-29 06:09:05

萬能指針C語言void

2024-01-29 00:30:00

C語言代碼數(shù)組

2009-07-31 15:10:21

C#函數(shù)指針數(shù)組C#數(shù)組

2015-03-09 09:34:04

C語言函數(shù)指針

2020-09-23 16:55:43

C語言編程語言

2009-01-08 09:26:06

C語言指針類型

2022-03-29 08:30:47

指針數(shù)組C語言
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久亚洲欧美日韩精品专区 | av中文字幕在线观看 | 日日干夜夜草 | 欧美精品一区二区在线观看 | 国产精品国产 | 国产1区2区在线观看 | 日韩成人在线观看 | 一区二区三区四区在线视频 | 99精品欧美一区二区三区综合在线 | 亚洲午夜久久久 | 中文字幕国产精品视频 | 日韩淫片免费看 | 国产一区二区在线看 | 精品一区二区三区四区 | 精品国产91亚洲一区二区三区www | 日韩一区二区三区视频在线播放 | 你懂的国产 | 欧美性视频在线播放 | 国产人成精品一区二区三 | 中文字幕不卡一区 | 日韩中出| 狠狠艹| 国产在线a | 91xxx在线观看 | 国产一级视频在线观看 | 日本黄色短片 | 色免费在线视频 | 黄色香蕉视频在线观看 | 欧洲精品一区 | 黄色网址大全在线观看 | 亚洲欧洲中文日韩 | www.av在线 | 国产高清视频在线观看 | 精品久久精品 | 91久久精 | 亚洲精品美女视频 | 在线观看亚洲一区二区 | 91青青草视频| 91av在线免费播放 | www.99re| 成人欧美一区二区三区在线播放 |