• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            指針和數組有著密切的關系,任何能由數組下標完成的操作也都可用指針來實現,但程序中使用指針可使代碼更緊湊、更靈活。

            一、指向數組元素的指針
                
            我們定義一個整型數組和一個指向整型的指針變量:
                    int a[10], *p; 
                
            和前面介紹過的方法相同,可以使整型指針p指向數組中任何一個元素,假定給出賦值運算
                    p=&a[0]; 
                
            此時,p指向數組中的第0號元素,a[0],指針變量p中包含了數組元素a[0]的地址,由于數組元素在內存中是連續存放的,因此,我們就可以通過指針變量p及其有關運算間接訪問數組中的任何一個元素。 
                Turbo C
            ,數組名是數組的第0號元素的地址,因此下面兩個語句是等價的
                    p=&a[0]; 
                    p=a; 
                
            根據地址運算規則,a+1a[1]的地址,a+i就為a[i]的地址。
                
            下面我們用指針給出數組元素的地址和內容的幾種表示形式:
                    (1). p+i
            a+i均表示a[i]的地址或者講,它們均指向數組第i號元素即指向a[i] 
                    (2). *(p+i)
            *(a+i)都表示p+ia+i所指對象的內容,即為a[i] 
                    (3). 
            指向數組元素的指針也可以表示成數組的形式,也就是說,它允許指針變量帶下標p[i]*(p+i)等價。
                         
            假若:        p=a+5; 
                             
            p[2]就相當于*(p+2), 由于p指向a[5], 所以p[2]就相當于a[7]。而p[-3]就相當于*(p-3), 它表示a[2]

            二、指向二維數組的指針 
                1.
            二維數組元素的地址 
                    
            為了說明問題我們定義以下二維數組:
                        int a[3][4]={{0,1,2,3}, {4,5,6,7}, {8,9,10,11}}; 
                            a
            為二維數組名,此數組有3412個元素。但也可這樣來理解,數組a由三個元素組成:a[0],a[1],a[2]。而每個元素又是一個一維數組且都含有4個元素(相當于4),例如,a[0]所代表的一維數組所包含的 4 個元素為a[0][0], a[0][1], a[0][2], a[0][3]。如圖所示
                                 ______        _______________
                            a---| a[0] | ____ | 0 | 1 | 2 | 3 |
                                |______|      |___|___|___|___|
                                | a[1] | ____ | 4 | 5 | 6 | 7 |
                                |______|      |___|___|___|___|
                                | a[2] | ____ | 8 | 9 | 10| 11|
                                |______|      |___|___|___|___|

                    
                    
            但從二維數組的角度來看,a代表二維數組的首地址,當然也可看成是二維數組第0行的首地址。a+1就代表第1行的首地址,a+2就代表第2行的首地址。如果此二維數組的首地址為1000,由于第0行有4個整型元素,所以a+11008,a+2也就為1016。如圖所示
                                               _______________
                                  (1000) ____ | 0 | 1 | 2 | 3 |
                                              |___|___|___|___|
                                  (1008) ____ | 4 | 5 | 6 | 7 |
                                              |___|___|___|___|
                                  (1016) ____ | 8 | 9 | 10| 11|
                                              |___|___|___|___|

                    
            既然我們把a[0],a[1],a[2]看成是一維數組名,可以認為它們分別代表它們所對應的數組的首地址,也就是講,a[0]代表第 0 行中第 0 列元素的地址,&a[0][0], a[1]是第1行中第0列元素的地址,&a[1][0],根據地址運算規則,a[0]+1即代表第0行第1列元素的地址,&a[0][1],一般而言,a[i]+j即代表第i行第j列元素的地址&a[i][j]
                    
            另外,在二維數組中,我們還可用指針的形式來表示各元素的地址。如前所述,a[0]*(a+0)等價,a[1]*(a+1)等價,因此a[i]+j就與*(a+i)+j等價,它表示數組元素a[i][j]的地址。
                    
            因此,二維數組元素a[i][j]可表示成*(a[i]+j)*(*(a+i)+j),它們都與a[i][j]等價,或者還可寫成(*(a+i))[j] 

                    
            另外要補充說明一下果你編寫一個程序輸出打印a*a,你可發現它們的值是相同的,這是為什么呢我們可這樣來理解
                        
            首先,為了說明問題,我們把二維數組人為地看成由三個數組元素a[0],a[1],a[2]組成,a[0],a[1],a[2]看成是數組名它們又分別是由4個元素組成的一維數組。因此,a表示數組第0行的地址*a即為a[0], 它是數組名當然還是地址,它就是數組第行第列元素的地址。
                2.
            指向一個由n個元素所組成的數組指針
                    
            Turbo C可定義如下的指針變量
                        int (*p)[3]; 
                    
            指針p為指向一個由3個元素所組成的整型數組指針。在定義中,圓括號是不能少的否則它是指針數組這將在后面介紹。這種數組的指針不同于前面介紹的整型指針,當整型指針指向一個整型數組的元素時,進行指針(地址)1運算,表示指向數組的下一個元素,此時地址值增加了2(因為放大因子為2),而如上所定義的指向一個由3個元素組成的數組指針,進行地址加1運算時,其地址值增加了6(放大因子為2x3=6), 
                    
            這種數組指針在Turbo C中用得較少,但在處理二維數組時還是很方便的。例如
                        int a[3][4], (*p)[4]; 
                        p=a; 
                    
            開始時p指向二維數組第0,當進行p+1運算時,根據地址運算規則,此時放大因子為4x2=8,所以此時正好指向二維數組的第1行。和二維數組元素地址計算的規則一樣,*p+1指向a[0][1],*(p+i)+j則指向數組元素a[i][j] 
                    
            例:
                        int a[3][4]={ 
                                      {1,3,5,7}, 
                                      {9,11,13,15}, 
                                      {17,19,21,23}
                                    }; 

                        main() 
                        { 
                            int i,(*b)[4]; 
                            b=a+1;     /* b
            指向二維數組的第1此時*b[0]a[1][0] */ 
                            for(i=1;i<=4;b=b[0]+2,i++)   /* 
            修改b的指向每次增加2 */ 
                            printf("%d\t",*b[0]); 
                            printf("\n"); 
                            for(i=0; i<3; i++)
                            { 
                                b=a+i;       /* 
            修改b的指向,每次跳過二維數組的一行 */ 
                                printf("%d\t",*(b[i]+1)); 
                            } 
                                printf ("\n"); 
                        }
                        
            程序運行結果如下
                             9    13   17   21 
                             3    11   19 

            三、字符指針 
                
            我們已經知道,字符串常量是由雙引號括起來的字符序列,例如
                    "a string" 
                
            就是一個字符串常量,該字符串中因為字符a后面還有一個空格字符,所以它由8個字符序列組成。在程序中如出現字符串常量C編譯程序就給字符串常量按排一存貯區域,這個區域是靜態的,在整個程序運行的過程中始終占用平時所講的字符串常量的長度是指該字符串的字符個數但在按排存貯區域時, C 編譯程序還自動給該字符串序列的末尾加上一個空字符'\0',用來標志字符串的結束,因此一個字符串常量所占的存貯區域的字節數總比它的字符個數多一個字節。
                Turbo C
            中操作一個字符串常量的方法有
                (1).
            把字符串常量存放在一個字符數組之中例如:
                        char s[]="a string"; 
                    
            數組s共有9個元素所組成,其中s[8]中的內容是'\0'。實際上,在字符數組定義的過程中,編譯程序直接把字符串復寫到數組中,即對數組s初始化。
                (2).
            用字符指針指向字符串,然后通過字符指針來訪問字符串存貯區域。當字符串常量在表達式中出現時
                    
            根據數組的類型轉換規則,它被轉換成字符指針。因此,若我們定義了一字符指針cp: 
                        char *cp; 
                    
            于是可用
                        cp="a string"; 
                    
            使cp指向字符串常量中的第0號字符a, 如圖所示。 
                                  
                                        ___________________________________
                            CP -----   | a |   | s | t | r | i | n | g | \0| 
                                       |___|___|___|___|___|___|___|___|___| 
                                                      
                    
            以后我們可通過cp來訪問這一存貯區域*cpcp[0]就是字符a,cp[i]*(cp+i)就相當于字符串的第i號字符,但企圖通過指針來修改字符串常量的行為是沒有意義的。 

            四、指針數組 
                
            因為指針是變量,因此可設想用指向同一數據類型的指針來構成一個數組這就是指針數組。數組中的每個元素都是指針變量,根據數組的定義,指針數組中每個元素都為指向同一數據類型的指針。指針數組的定義格式為
                     
            類型標識 *數組名[整型常量表達式]; 
                
            例如
                     int *a[10]; 
                
            定義了一個指針數組,數組中的每個元素都是指向整型量的指針,該數組由10個元素組成,a[0],a[1],a[2], ..., a[9],它們均為指針變量。a為該指針數組名,和數組一樣,a是常量,不能對它進行增量運算。a為指針數組元素a[0]的地址,a+ia[i]的地址,*a就是a[0],*(a+i)就是a[i]
                
            為什么要定義和使用指針數組呢?主要是由于指針數組對處理字符串提供了更大的方便和靈活,使用二維數組對處理長度不等的正文效率低,而指針數組由于其中每個元素都為指針變量,因此通過地址運算來操作正文行是十分方便的。
                
            指針數組和一般數組一樣,允許指針數組在定義時初始化,但由于指針數組的每個元素是指針變量,它只能存放地址,所以對指向字符串的指針數組在說明賦初值時,是把存放字符串的首地址賦給指針數組的對應元素
                
            例如下面是一個書寫函數month_name(n),函數返回一個指向包含第n月名字的字符指針(關于函數指針和指針函數,下一節將專門介紹) 
                          
                
            打印1月至12月的月名
                    char *month_name(int n) 
                    { 
                         static char *name[]={ 
                                                "Illegal month", 
                                                "January", 
                                                "February", 
                                                "March", 
                                                "April", 
                                                "May", 
                                                "June", 
                                                "July", 
                                                "August", 
                                                "September", 
                                                "October", 
                                                "November", 
                                                "December" 
                                             }; 
                         return((n<1||n>12)?name[0]:name[n]); 
                    } 

                    main() 
                    { 
                        int i; 
                        for(i=0; i<13; i++) 
                            printf("%s\n", month_name(i)); 
                    }

            對于指針這一節,一定要多練習一些題。指針是一個很重要的概念,必須多接觸實際的問題才能掌握它。
            Posted on 2005-11-03 10:06 艾凡赫 閱讀(1830) 評論(1)  編輯 收藏 引用 所屬分類: 數據類型

            Feedback

            # re: 數組和指針  回復  更多評論   

            2012-08-22 16:40 by 劉偉
            不錯!贊一個
            国产精品美女久久福利网站| 久久伊人五月天论坛| 狼狼综合久久久久综合网| 国产精品美女久久久久网| 久久久久久亚洲精品不卡 | 四虎国产精品免费久久5151| 精品国产综合区久久久久久| 久久精品国产免费观看 | 九九久久精品国产| 亚洲国产美女精品久久久久∴| 亚洲国产精品久久久久婷婷软件 | 国产福利电影一区二区三区久久久久成人精品综合 | 91麻精品国产91久久久久| 久久狠狠爱亚洲综合影院| 9999国产精品欧美久久久久久| 亚洲午夜无码久久久久| 久久夜色撩人精品国产| 亚洲国产精品久久久久| 97久久精品国产精品青草| 国产毛片欧美毛片久久久| 久久av免费天堂小草播放| 亚洲国产精品久久久久| 日韩乱码人妻无码中文字幕久久| 日韩va亚洲va欧美va久久| 精品99久久aaa一级毛片| 亚洲精品高清国产一久久| 久久国产亚洲高清观看| 久久久久亚洲AV成人网人人网站| 久久免费大片| 久久久久人妻一区精品果冻| 久久不见久久见免费影院www日本| 99999久久久久久亚洲| 精品久久久久久久无码| 久久精品中文无码资源站| 99精品久久精品一区二区| 一级a性色生活片久久无| 婷婷久久综合九色综合绿巨人| 久久综合伊人77777麻豆| 久久久久久国产a免费观看黄色大片| 欧美午夜精品久久久久久浪潮| 久久综合九色综合欧美就去吻|