久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

指針與數(shù)組

 haishukongmu 2016-09-23

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//指針與數(shù)組

  • 指針與地址
  • 指針與函數(shù)參數(shù)
  • 指針與數(shù)組
  • 地址算術(shù)運(yùn)算
  • 字符指針與函數(shù)
  • 指針數(shù)組以及指向指針的指針
  • 多維數(shù)組
  • 指針數(shù)組的初始化
  • 指針與多為數(shù)組
  • 命令行參數(shù)
  • 指向函數(shù)的指針
  • 復(fù)雜聲明

//指針與地址

一元運(yùn)算符&可用于取一個(gè)對(duì)象的地址,。如:

        p=&c;

將把c的地址賦值給變量p,,則稱(chēng)p為指向c的指針。地址運(yùn)算符&只能應(yīng)用于內(nèi)存中的對(duì)象,,即變量與數(shù)組元素,。它不能作用于表達(dá)式,常量或register類(lèi)型的變量,。

一元運(yùn)算符*是間接尋址或間接引用運(yùn)算符,。當(dāng)它作用于指針時(shí),將訪問(wèn)指針?biāo)赶虻膶?duì)象,。假定x與y是整數(shù),,而ip是指向int類(lèi)型的指針,下面的代碼說(shuō)明了如何在程序中聲明指針以及如何使用運(yùn)算符&和*:

        int x=1 , y=2 ,z[10];

        int *ip;                              // ip is a pointer to int

        ip=&x;                              // ip now points to x

        y=*ip;                               // y is now 1

        *ip=0;                              // x is now 0

        ip=&z[0];                         // ip now points to z[0]

注意:指針只能指向某種特定類(lèi)型的對(duì)象,,即每個(gè)指針都必須指向某種特定的數(shù)據(jù)類(lèi)型,。

一個(gè)例外情況是指向void類(lèi)型的指針可以存放指向任何類(lèi)型的指針,,但它不能間接引用其自身。

//指針與函數(shù)參數(shù)

由于C語(yǔ)言是以傳值的方式將參數(shù)值傳遞給被調(diào)用函數(shù),。因此,,被調(diào)用函數(shù)不能直接修改主調(diào)函數(shù)中變量的值。

指針參數(shù)使得被調(diào)用函數(shù)能夠訪問(wèn)和修改主調(diào)函數(shù)中對(duì)象的值,。

//指針與數(shù)組

在C語(yǔ)言中,,通過(guò)數(shù)組下標(biāo)所能完成的任何操作都可以通過(guò)指針來(lái)實(shí)現(xiàn)。一般來(lái)講,,用指針編寫(xiě)的程序比用數(shù)組下標(biāo)編寫(xiě)的程序執(zhí)行速度快,,但另一方面,用指針實(shí)現(xiàn)的程序理解比較困難,。

聲明

        int a[10];

定義了一個(gè)長(zhǎng)度為10的數(shù)組a,。即定義了一個(gè)由10個(gè)對(duì)象組成的集合,這10個(gè)對(duì)象存儲(chǔ)在相鄰的內(nèi)存區(qū)域中,,名字分別為a[0],,a[1],a[2],,...,,a[9]。

        a:|____|____|____|____|____|____|____|____|____|____|

              a[0]   a[1]   a[2]                                                 a[9]

        a[i]表示該數(shù)組的第i個(gè)元素,。如果pa的聲明為

                int *pa;

        則說(shuō)明它是一個(gè)指向整型對(duì)象的指針,,那么,,賦值語(yǔ)句

                pa=&a[0];

        則可以將指針pa指向數(shù)組a的第0個(gè)元素,,也就是說(shuō),pa的值為數(shù)組元素a[0]的地址

        那么,,賦值語(yǔ)句

                x=*pa;

        將把數(shù)組元素a[0]中的內(nèi)容復(fù)制到變量x中,。

        如果pa指向數(shù)組中的某個(gè)特定元素,那么,,根據(jù)指針運(yùn)算的定義,,pa+1將指向下一個(gè)元素,pa+i將指向pa所指向元素之后的第i個(gè)元素,,而pa-i將指向pa所指向數(shù)組元素之前的第i個(gè)元素,。因此,如果指針pa指向a[0],,那么*(pa+1)引用的是數(shù)組元素a[1]的內(nèi)容,,pa+i是數(shù)組元素a[i]的地址,*(pa+i)引用的是數(shù)組元素a[i]的內(nèi)容,。


下標(biāo)和指針運(yùn)算之間有密切的對(duì)應(yīng)關(guān)系,。根據(jù)定義,,數(shù)組類(lèi)型的變量或表達(dá)式的值是該數(shù)組第0個(gè)元素的地址。執(zhí)行賦值語(yǔ)句:

        pa=&a[0];

后,,pa和a具有相同的值,。因?yàn)閿?shù)組名所代表的就是該數(shù)組最開(kāi)始的一個(gè)元素的地址,所以,,賦值語(yǔ)句pa=&a[0]也可以簡(jiǎn)寫(xiě)為:

        pa=a;

對(duì)于數(shù)組元素a[i]的引用也可以寫(xiě)成*(a+i)的形式,。在計(jì)算數(shù)組元素a[i]的值時(shí),C語(yǔ)言實(shí)際上先將其轉(zhuǎn)換為*(a+1)的形式,,然后再進(jìn)行求值,,因此在程序中這兩種形式是等價(jià)的。如果對(duì)這兩種等價(jià)的表示形式分別施加地址運(yùn)算符&,,便可得出這樣的結(jié)論:&a[i]和a+i的含義也是相同的,。a+i是a之后第i個(gè)元素的地址。相應(yīng)的,,如果pa是個(gè)指針,,那么,在表達(dá)式中也可以在它的后面加下標(biāo),。pa[i]與*(pa+i)是等價(jià)的,。簡(jiǎn)言之,一個(gè)通過(guò)數(shù)組和下標(biāo)實(shí)現(xiàn)的表達(dá)式可等價(jià)地通過(guò)指針和偏移量實(shí)現(xiàn),。


但是,,數(shù)組名和指針之間有一個(gè)不同之處,指針是一個(gè)變量,,因此,,在C語(yǔ)言中,語(yǔ)句pa=a和pa++都是合法的,。但數(shù)組名不是變量,,因此,類(lèi)似于a=pa和a++形式的語(yǔ)句是非法的,。

當(dāng)數(shù)組名傳遞給一個(gè)函數(shù)時(shí),,實(shí)際上傳遞的是該數(shù)組第一個(gè)元素的地址。在被調(diào)用函數(shù)中,,該參數(shù)是一個(gè)局部變量,,因此,數(shù)組名參數(shù)必須是一個(gè)指針,,也就是一個(gè)存儲(chǔ)地址值的變量,。可以利用該特性辨析strlen函數(shù)的另一個(gè)版本,,該函數(shù)用于計(jì)算一個(gè)字符串的長(zhǎng)度,。

        // strlen: return length of string s

        int strlen(char *s)

        {

                int n;

                for(n=0; *s!='\0';s++)

                        n++;

                return n;

        }

因?yàn)閟是一個(gè)指針,,所以對(duì)其執(zhí)行自增運(yùn)算是合法的。執(zhí)行s++運(yùn)算不會(huì)影響到strlen函數(shù)的調(diào)用者中的字符串,,它僅對(duì)該指針在strlen函數(shù)中的私有副本進(jìn)行自增運(yùn)算,。因此,類(lèi)似于下面這樣的函數(shù)調(diào)用:

        strlen("hello world");                               // string constant

        strlen(array);                                          // char array[100]

        strlen(ptr);                                              // char *ptr

都是正確的,。

在函數(shù)定義中,,形式參數(shù)

        char s[];

        char *s;

是等價(jià)的。通常習(xí)慣使用后一種形式,,因?yàn)樗惹罢吒庇^地表明了該參數(shù)是一個(gè)指針,。如果將數(shù)組名傳遞給函數(shù),函數(shù)可以根據(jù)情況判定是按照數(shù)組處理還是按照指針處理,,隨后根據(jù)相應(yīng)的方式操作該參數(shù),。為了直觀且恰當(dāng)?shù)孛枋龊瘮?shù),在函數(shù)中甚至可以同時(shí)使用數(shù)組和指針這兩種表示方法,。


也可以將指向子數(shù)組起始位置的指針傳遞給函數(shù),,這樣,就將數(shù)組的一部分傳遞給了函數(shù),。例如,,如果a是一個(gè)數(shù)組,那么下面兩個(gè)函數(shù)調(diào)用:

        f(&a[2]);

        f(a+2);

都將把起始于a[2]的子數(shù)組的地址傳遞給函數(shù)f,。在函數(shù)f中,,參數(shù)的聲明形式可以為

        f(int arr[]){ ... }

        f(int *arr){ ... }

對(duì)于函數(shù)f來(lái)講,它并不關(guān)心所引用的是否只是一個(gè)更大數(shù)組的部分元素,。

如果確信相應(yīng)的元素存在,,也可以通過(guò)下標(biāo)訪問(wèn)數(shù)組第一個(gè)元素之前的元素。類(lèi)似于p[-1],,p[-2]這樣的表達(dá)式在語(yǔ)法上都是合法的,,它們分別引用位于p[0]之前的兩個(gè)元素。當(dāng)然,,引用數(shù)組邊界之外的對(duì)象是非法的。

//地址算術(shù)運(yùn)算

如果p是一個(gè)指向數(shù)組中某個(gè)元素的指針,,那么p++將對(duì)p進(jìn)行自增運(yùn)算并指向下一個(gè)元素,,而p+=i將對(duì)p進(jìn)行加i的增量運(yùn)算,使其指向指針p當(dāng)前所指向的元素之后的第i個(gè)元素,。這類(lèi)運(yùn)算是指針或地址算術(shù)運(yùn)算中最簡(jiǎn)單的形式,。

一般情況下,同其他類(lèi)型的變量一樣,,指針也可以初始化,。通常,,對(duì)指針有意義的初始化值只能是0或者是表示地址的表達(dá)式,對(duì)后者來(lái)說(shuō),,表達(dá)式所代表的地址必須是在此前已定義的具有適當(dāng)類(lèi)型的數(shù)據(jù)的地址,。例如,聲明

        static char* allocp=allocbuf;

將allocp定義為字符類(lèi)型指針,,并將它初始化為allocbuf的起始地址,,該起始地址是程序執(zhí)行時(shí)的下一個(gè)空閑位置。上述語(yǔ)句也可以寫(xiě)成下列形式:

        static char* allocp=&allocbuf[0];

這是因?yàn)樵摂?shù)組名實(shí)際上就是數(shù)組第0個(gè)元素的地址,。

指針與整數(shù)之間不能相互轉(zhuǎn)換,,但0是唯一的例外,常量0可以賦值給指針,,指針也可以和常量0進(jìn)行比較,。程序中經(jīng)常使用符合常量NULL代替常量0,這樣便于更清晰的說(shuō)明常量0是指針的一個(gè)特殊值,。符號(hào)常量NULL定義在標(biāo)準(zhǔn)頭文件<stddef.h>中,。


指針?biāo)阈g(shù)運(yùn)算有以下幾個(gè)重要特點(diǎn):

首先,在某些情況下對(duì)指針可以進(jìn)行比較運(yùn)算,。例如,,如果指針p和q指向同一個(gè)數(shù)組的成員,那么它們之間就可以進(jìn)行類(lèi)似于==,!=,<,>=的關(guān)系比較運(yùn)算,。如果p指向的數(shù)組元素的位置q指向的數(shù)組元素位置之前,,那么關(guān)系表達(dá)式

        p<q

的值為真。任何指針與0進(jìn)行相等或不等的比較運(yùn)算都有意義,。但是,,指向不同數(shù)組的元素的指針之間的算術(shù)或比較運(yùn)算沒(méi)有意義。(特例:指針的算術(shù)運(yùn)算中可使用數(shù)組最后一個(gè)元素的下一個(gè)元素的地址)

其次,,指針可以和整數(shù)進(jìn)行相加或相減運(yùn)算,。例如,結(jié)構(gòu)

        p+n

表示指針p當(dāng)前指向的對(duì)象之后第n個(gè)對(duì)象的地址,。無(wú)論指針p指向的對(duì)象是何種類(lèi)型,,上述結(jié)論都成立。在計(jì)算p+n時(shí),,n將根據(jù)p指向的對(duì)象的長(zhǎng)度按比例縮放,,而p指向的對(duì)象的長(zhǎng)度則取決于p的聲明。例如,,如果int類(lèi)型占4字節(jié)的存儲(chǔ)空間,,那么在int類(lèi)型的計(jì)算中,對(duì)應(yīng)的n將按4的倍數(shù)來(lái)計(jì)算。

指針的減法運(yùn)算也是有意義的,,如果p和q指向相同的數(shù)組元素,,且p<q,那么q-p+1就是位于p和q指向的元素之間的元素的數(shù)目,。由此可以編寫(xiě)出函數(shù)strlen的另一個(gè)版本:

        // strlen: return length of string s

        int strlen(char *s)

        {

                char *p=s;

                while(*p!='\0')

                        p++;

                return p-s;

        }

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

注意:字符串中的字符數(shù)有可能超過(guò)int類(lèi)型所能表示的最大范圍,。頭文件<stddef.h>中定義的類(lèi)型ptrdiff_t足以表示兩個(gè)指針之間的帶符號(hào)差值。但是,,在這里使用size_t作為函數(shù)strlen的返回值類(lèi)型,,這樣可以與標(biāo)準(zhǔn)庫(kù)中的函數(shù)版本相匹配。size_t是由運(yùn)算符sizeof返回的無(wú)符號(hào)整型,。

有效的指針運(yùn)算包括相同類(lèi)型指針之間的賦值運(yùn)算,;指針同整數(shù)之間的加法或減法運(yùn)算;指向相同數(shù)組中元素的兩個(gè)指針間的減法或比較運(yùn)算,;將指針賦值為0或指針與0之間的比較運(yùn)算,。其他所有形式的指針運(yùn)算都是非法的,例如兩個(gè)指針間的加法,、乘法,、除法、移位或屏蔽運(yùn)算,;指針同float或double類(lèi)型之間的加法運(yùn)算,;不經(jīng)強(qiáng)制類(lèi)型轉(zhuǎn)換而直接將指向一種類(lèi)型對(duì)象的指針賦值給指向另一種類(lèi)型對(duì)象的指針的運(yùn)算(兩個(gè)指針之一是void*類(lèi)型的情況除外)。

//字符指針與函數(shù)

字符串常量是一個(gè)字符數(shù)組,,例如:

        “I am a string"

在字符串的內(nèi)部表示中,,字符數(shù)組以空字符‘\0’結(jié)尾,所以,,程序可以通過(guò)檢查空字符找到字符數(shù)組的結(jié)尾,。字符串常量占據(jù)的存儲(chǔ)單元數(shù)也因此比雙引號(hào)內(nèi)的字符數(shù)大1。


字符串常量最常見(jiàn)的用法也許是作為函數(shù)參數(shù),,如:

        printf("hello, world\n");

當(dāng)類(lèi)似于這樣的一個(gè)字符串出現(xiàn)在程序中時(shí),實(shí)際上是通過(guò)字符指針訪問(wèn)該字符串的。在上述語(yǔ)句中,,printf接受的是一個(gè)指向字符數(shù)組第一個(gè)字符的指針,。也就是說(shuō),字符串常量可通過(guò)一個(gè)指向其第一個(gè)元素的指針訪問(wèn),。

除了作為函數(shù)參數(shù)外,,字符串常量還有其他用法。假定指針pmessage的聲明如下:

        char *pmessage,;

那么,,語(yǔ)句

        pmessage="now is the time";

將把一個(gè)指向該字符數(shù)組的指針賦值給pmessage。該過(guò)程并沒(méi)有進(jìn)行字符串的復(fù)制,,而只是涉及到指針的操作,。C語(yǔ)言沒(méi)有提供將整個(gè)字符串作為一個(gè)整體進(jìn)行處理的運(yùn)算符。

下面兩種定義之間有很大的差別:

        char amessage[]="now is the time";   //定義一個(gè)數(shù)組

        char *pmessage="now is the time";    //定義一個(gè)指針

其中,,amessage是一個(gè)僅僅足以存放初始化字符串以及空字符'\0'的一維數(shù)組,。數(shù)組中的單個(gè)字符可以進(jìn)行修改,但是amessage始終指向同一個(gè)存儲(chǔ)位置,。另一方面,,pmessage是一個(gè)指針,其初始值指向一個(gè)字符串常量,,之后它可以被修改以指向其他地址,,但如果試圖修改字符串的內(nèi)容,結(jié)果是不可確定的,。

為了更近一部討論指針和數(shù)組其他方面的問(wèn)題,,下面以標(biāo)準(zhǔn)庫(kù)中兩個(gè)有用的函數(shù)為例來(lái)說(shuō)明。

第一個(gè)函數(shù)strcpy(s,,t),,把指針t指向的字符串復(fù)制到指針s指向的位置。如果使用語(yǔ)句s=t實(shí)現(xiàn)該功能,,其實(shí)質(zhì)上只是拷貝了指針,,而并沒(méi)有賦值字符。為了進(jìn)行字符的復(fù)制,,這里使用了一個(gè)循環(huán)語(yǔ)句,。strcpy函數(shù)的第一個(gè)版本是通過(guò)數(shù)組方法實(shí)現(xiàn)的,如下:

        // strcpy :copy t to s; array subscript version

        void strcpy(char *s, char *t)

        {

                int i;

                i=0;

                while(( s[i] = t[i] ) !='\0')

                        i++;

        }

下面使用指針?lè)椒▽?shí)現(xiàn)strpy函數(shù)

        //strcpy : copy t to s; pointer version

        void strcpy(char *s, char *t)

        {

                int i;

                i=0;

                while( ( *s = *t ) != '\0' )

                {

                        s++;

                        t++;

                }

        }

因?yàn)閰?shù)是通過(guò)值傳遞的,,所以在strcpy函數(shù)中可以以任何方式使用參數(shù)s和t,。在此,s和t是方便地進(jìn)行了初始化的指針,,循環(huán)每執(zhí)行一次,,他們就沿著相應(yīng)的數(shù)組前進(jìn)一個(gè)字符,直到將t中的結(jié)束符'\0'復(fù)制到s為止。

實(shí)際上,,strcpy函數(shù)并不會(huì)按照上面的這些方式編寫(xiě),。經(jīng)驗(yàn)豐富的程序員更喜歡對(duì)它編寫(xiě)成下列形式:

        // strcpy : copy t to s; pointer version 2

        void strcpy(char *s, char *t)

        {

                while( (*s++ = *t++) != ‘\0’ )

                        ;

        }

在該版本中,s和t的自增運(yùn)算放到了循環(huán)的測(cè)試部分中,。表達(dá)式*t++的值是執(zhí)行自增運(yùn)算之前t所指向的字符,。后綴運(yùn)算符++表示在讀取該字符之后才改變t的值。同理,,在s執(zhí)行自增運(yùn)算前,,字符就被存儲(chǔ)到指針s指向的舊位置。該字符值同時(shí)也用來(lái)和空字符'\0'進(jìn)行比較運(yùn)算,,以控制循環(huán)的執(zhí)行,。最后的結(jié)果是依次將t指向的字符復(fù)制到s指向的位置,知道遇到結(jié)束符位置(同時(shí)也復(fù)制該結(jié)束符),。

為了更進(jìn)一步的精煉程序,,我們注意到,表達(dá)式同'\0'的比較是多余的,,因?yàn)橹恍枰卸ū磉_(dá)式的值是否為0即可,。因此,該函數(shù)可進(jìn)一步寫(xiě)成下列形式:

        // strcpy : copy t to s; pointer version 3

        void strcpy(char *s , char *t)

        {

                while(*s++=*t++)

                        ;

        }

該函數(shù)初看起來(lái)不太容易理解,,但這種表示方法很有好處,,應(yīng)該掌握此種方法,C語(yǔ)言程序中經(jīng)常會(huì)采用這種寫(xiě)法,。

標(biāo)準(zhǔn)庫(kù)<string.h>中提供的函數(shù)strcpy把目標(biāo)字符串作為函數(shù)值返回,。

第二個(gè)函數(shù)是strcmp(s,t)。該函數(shù)比較字符串s和t,,并且根據(jù)s按照字典順序小于,、等于或大于t的結(jié)果分別返回負(fù)整數(shù)、0或正整數(shù),。該返回值是s和t由前向后逐字符比較時(shí)遇到的第一個(gè)不相等字符處的字符的差值,。

        // strcmp : return <0 is s<t, 0 if s==t, >0 if s>t

        int strcmp(char *s, char *t)

        {

                int i;

                for(i=0; s[i]==t[i];i++)

                        if(s[i]=='\0')

                                return 0;

                return s[i]-t[i];

        }

下面是用指針?lè)绞綄?shí)現(xiàn)

        // strcmp return <0 if s<t,  0 if s==t, >0 if s>t

        int strcmp(char *s, char *t)

        {

                for(; *s==*t; s++, t++)

                        if(*s=='\0')

                                return 0;

                return *s-*t;

        }

由于++和--既可以作為前綴,也可以作為后綴運(yùn)算符,,所以還可以將運(yùn)算符*與運(yùn)算符++和--按照其他方式組合使用,,但這些用法不多見(jiàn)。例如,,

        *--p;

在讀取制作p指向的字符之前先對(duì)p指向自減運(yùn)算,。事實(shí)上,下面的兩個(gè)表達(dá)式:

        *p++=val;             //將val壓入棧

        val=*--p;              //將棧頂元素彈出到val中

是進(jìn)棧和出棧的標(biāo)準(zhǔn)用法,。

//指針數(shù)組以及指向指針的指針

指針數(shù)組,,其定義方式如下:

        char lineptr[MAXLINES];   // getline函數(shù)

它表示lineptr是一個(gè)具有MAXLINES個(gè)元素的一維數(shù)組,,其中數(shù)組的每個(gè)元素是一個(gè)指向字符類(lèi)型對(duì)象的指針。也就是說(shuō),,lineptr[i]是一個(gè)字符指針,,而*lineptr[i]是該指針指向的第i個(gè)文本行的首字符,。

//多維數(shù)組

在C語(yǔ)言里,,二位數(shù)組實(shí)際是一種特殊的一維數(shù)組,它的每個(gè)元素也是一個(gè)一維數(shù)組,。

數(shù)組可以用花括號(hào)括起來(lái)的初值表進(jìn)行初始化,,二維數(shù)組的每一行由相應(yīng)的子列表進(jìn)行初始化。

注意:

        int daytab[3][12];

如果將二維數(shù)組作為參數(shù)傳遞給函數(shù),,那么在函數(shù)的參數(shù)聲明中必須指名數(shù)組的列數(shù),。數(shù)組的行數(shù)沒(méi)有太大關(guān)系,函數(shù)調(diào)用時(shí)傳遞的是一個(gè)指針,,它指向由行向量構(gòu)成的一維數(shù)組,,其中每個(gè)行向量是具有13個(gè)整型元素的一維數(shù)組。在該例子中,,傳遞給函數(shù)的是一個(gè)指向很多對(duì)象的指針,,其中每個(gè)對(duì)象是由13個(gè)整型元素構(gòu)成的一維數(shù)組。因此,,如果將數(shù)組daytab作為參數(shù)傳遞給函數(shù)f,,那么f的格式應(yīng)寫(xiě)作:

        f( int daytab[3][13] ){...}

        f( int daytab[][13] ){...}

因?yàn)閿?shù)組的函數(shù)無(wú)關(guān)緊要,所以,,該聲明還可寫(xiě)成

        f( int (*daytab)[13])

這種聲明形式表明參數(shù)是一個(gè)指針,,它指向具有13個(gè)整型元素的一維數(shù)組。因此方括號(hào)[]的優(yōu)先級(jí)高于*的優(yōu)先級(jí),,所以上述聲明中必須使用圓括號(hào),。如果去掉括號(hào),則聲明變成

        int *daytab[13]

這相當(dāng)于聲明了一個(gè)數(shù)組,,概述組有13個(gè)元素,,其中每個(gè)元素都是一個(gè)指向整型對(duì)象的指針。一般來(lái)說(shuō),,除數(shù)組的第一維下標(biāo)可以不指定大小外,,其余各維都必須明確指定大小。

//指針數(shù)組的初始化

//指針與多維數(shù)組

二位數(shù)組與指針數(shù)組之間的區(qū)別,。假如有下面兩個(gè)定義:

        int a[10][21];

        int *b[10];

那么,,從語(yǔ)法角度講,a[3][4]和b[3][4]都是對(duì)一個(gè)int對(duì)象的合法引用,。但a是一個(gè)真正的二維數(shù)組,,它分配了200個(gè)int類(lèi)型長(zhǎng)度的存儲(chǔ)空間,,并且通過(guò)常規(guī)的矩陣下標(biāo)計(jì)算公式20*row+col(row行,col列)計(jì)算得到a[row][col]的位置,。但是,,對(duì)b來(lái)說(shuō),該定義僅僅分配了10個(gè)指針,,并且沒(méi)有對(duì)它們初始化,,它們的初始化必須以顯式的方式進(jìn)行,比如靜態(tài)初始化或通過(guò)代碼初始化,。假定b的每個(gè)元素都指向一個(gè)具有20個(gè)元素的數(shù)組,,那么編譯器就要為它分配200個(gè)int類(lèi)型長(zhǎng)度的存儲(chǔ)空間以及10個(gè)指針的存儲(chǔ)空間。指針數(shù)組的一個(gè)重要優(yōu)點(diǎn)在于,,數(shù)組的每一行長(zhǎng)度可以不同,,也就是說(shuō),b的每個(gè)元素不必都指向一個(gè)具有20個(gè)元素的向量,,某些元素可以指向具有2個(gè)元素的向量,,某些元素可以指向有50個(gè)元素的向量,而某些元素可以不指向任何向量,。

指針數(shù)組最頻繁的用處是存放具有不同長(zhǎng)度的字符串,,如下定義:

        char *name[]={"Illegal month","Jan","Feb","Mar"};

下面是二維數(shù)組的聲明:

        char aname[][15]={"Illegal month", "Jan", "Feb", "Mar"};

下面是指針數(shù)組和二維數(shù)組的圖形化描述:

//命令行參數(shù)

在支持C語(yǔ)言的環(huán)境中,可以在程序開(kāi)始執(zhí)行時(shí)將命令行參數(shù)傳遞給程序,。調(diào)用主函數(shù)main時(shí),,它帶有兩個(gè)參數(shù)。第一個(gè)參數(shù)(習(xí)慣上成為argc,,用與參數(shù)計(jì)數(shù))的值表示運(yùn)行程序時(shí)命令行中參數(shù)的數(shù)目,;第二個(gè)參數(shù)(稱(chēng)為argv,用于參數(shù)向量)是一個(gè)指向字符串?dāng)?shù)組的指針,,其中每個(gè)字符串對(duì)應(yīng)一個(gè)參數(shù),。通常使用多級(jí)指針處理這些字符串。

按照C語(yǔ)言的約定,,argv[0]的值是啟動(dòng)該程序的程序名,,因此argc的值至少為1。另外,,ANSI標(biāo)準(zhǔn)要求argv[argc]的值必須為一空指針,。




/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//在C語(yǔ)言中,指針和數(shù)組名通常都可以混用,。

如:

        char *p;       // *p=p[0],,*(p+1)=p[1]

        char b[5];    // b[0]=*b,b[2]=*(b+2)


在一般的通信中(如串口),,通常都使用字節(jié)傳輸,。而像float,,long,int之類(lèi)的,,有4個(gè)字節(jié),。我的方法就是取它的地址,強(qiáng)制轉(zhuǎn)換為char型指針,,然后當(dāng)作數(shù)組來(lái)用,。

        float x;

        SBUF=((char*)&x)[0];

        SBUF=((char*)&x)[1];

        SBUF=((char*)&x)[2];

        SBUF=((char*)&x)[3];

接收時(shí),剛好倒過(guò)來(lái),。更有趣的是,,對(duì)于數(shù)組形式,,數(shù)組名和后面的偏移量可以隨便換,。

        char buff[10];       //或者用char *buff=&buffer;

        buff[3]=0xaa;

        3[buff]=0xaa;       //兩者是一樣的

因此,,可以認(rèn)為編譯器是這么認(rèn)為的,對(duì)于形如xxx[yyy]這樣的表達(dá)式,,會(huì)轉(zhuǎn)化為*(xxx+yyy),因此兩種形式都是一樣的,。



//數(shù)組名和指針的區(qū)別

  • 數(shù)組名的內(nèi)涵在于其指代實(shí)體是一種數(shù)據(jù)結(jié)構(gòu),,這種數(shù)據(jù)結(jié)構(gòu)就是數(shù)組(如示例1中: sizeof(str)=10)
  • 數(shù)組名的外延在于其可以轉(zhuǎn)換為指向其指代實(shí)體的指針,而且是一個(gè)指針常量(如示例2中: strcpy(str2,str1))
  • 指向數(shù)組的指針則是另外一種變量類(lèi)型,,僅僅意味著數(shù)組的存放地址

        注意:雖然數(shù)組名可以轉(zhuǎn)換為指向其指代實(shí)體的指針,,但是它只能被看作一個(gè)指針常量,不能被修改,,如下:

                int intArray[10];

                intArray++;            //錯(cuò)誤


1.數(shù)組名不是指針

示例程序1

示例程序1執(zhí)行結(jié)果:

        str len=10

        pStr len=4

執(zhí)行示例程序可知:sizeof(str)=10,,sizeof(pStr)=4,可見(jiàn)數(shù)組名和指針是不一樣的

2.數(shù)組名神似指針

示例程序2

示例程序2執(zhí)行結(jié)果:

        str is:I miss u
        pStr is:I miss u

標(biāo)準(zhǔn)C庫(kù)函數(shù)strcpy的函數(shù)原型中能接納的兩個(gè)參數(shù)都為char型指針,,而示例程序中傳給它的確實(shí)兩個(gè)數(shù)組名,。

3.數(shù)組名可能失去其數(shù)據(jù)結(jié)構(gòu)內(nèi)涵

示例程序3

示例程序3執(zhí)行結(jié)果:str len=4

分析:

        數(shù)組名作為函數(shù)形參時(shí),在函數(shù)體內(nèi),,其失去了本身的內(nèi)涵,,僅僅只是一個(gè)指針;

        在失去其內(nèi)涵的同時(shí),,它還失去了其常量特性,,可以作自增,自減等操作,,可以被修改,;

結(jié)果:

        所以數(shù)組名作為函數(shù)形參時(shí),就是一個(gè)普通的指針,,4字節(jié)



//(*(a+1))和(&a+1)的區(qū)別

*(a+1)和(&a+1)

程序執(zhí)行結(jié)果:

        *(a+1)=2,*(ptr-1)=5
顯然*(a+1)=a[1],,而&a+1是什么呢,?&a不是首地址加1,而是加上1個(gè)a數(shù)組大小的偏移(sizeof(a)),。所以ptr=a+5,,*(ptr-1)=a[4]。因?yàn)椋相當(dāng)于一個(gè)數(shù)組指針int (*)[5],,該指針加1相當(dāng)于移動(dòng)5個(gè)int的存儲(chǔ)空間,,因此ptr=a+5.(參考:http://www.cnblogs.com/dolphin0520/archive/2011/09/26/2191985.html)



    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多