機電之家資源網(wǎng)
單片機首頁|單片機基礎|單片機應用|單片機開發(fā)|單片機文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓信息
贊助商
學C51的基礎 9 《 指針、結構、聯(lián)合和枚舉 》 作者[cmh]©
學C51的基礎 9 《 指針、結構、聯(lián)合和枚舉 》 作者[cmh]©
 更新時間:2008-8-17 16:34:10  點擊數(shù):42
【字體: 字體顏色

    假若:      p=a+5;
則p[2]就相當于*(p+2),由于p指向a[5], 所以p[2]就相當于a[7]。而p[-3]就相當于*(p-3),它表示a[2].

    2.2. 指向二維數(shù)組的指針
    2.2.1. 二維數(shù)組元素的地址
    為了說明問題, 我們定義以下二維數(shù)組:

     int a[3][4]={{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};

a為二維數(shù)組名, 此數(shù)組有3行4列, 共12個元素。但也可這樣來理解, 數(shù)組a由三個元素組成:a[0],a[1],a[2]。而它勻中每個元素又
是一個一維數(shù)組, 且都含有4個元素 (相當于4列), 例如 a[0]所代表的一維數(shù)組所包含的 4 個元素為a[0][0], a[0][1], a[0][2],
a[0][3]。如圖5.所示:
        ┏━━━━┓    ┏━┳━┳━┳━┓
  a─→ ┃  a[0]  ┃─→┃0 ┃1 ┃2 ┃3 ┃
        ┣━━━━┫    ┣━╋━╋━╋━┫
        ┃  a[1]  ┃─→┃4 ┃5 ┃6 ┃7 ┃
        ┣━━━━┫    ┣━╋━╋━╋━┫
        ┃  a[2]  ┃─→┃8 ┃9 ┃10┃11┃
        ┗━━━━┛    ┗━┻━┻━┻━┛
                    圖5.

    但從二維數(shù)組的角度來看, a代表二維數(shù)組的首地址, 當然也可看成是二維數(shù)組第0行的首地址。a+1就代表第1行的首地址, a+2
就代表第2行的首地址。如果此二維數(shù)組的首地址為1000, 由于第0行有4個整型元素, 所以a+1為1008, a+2也就為1016。如圖6.
所示
                            a[3][4]

                   a    ┏━┳━┳━┳━┓
              (1000)─→┃0 ┃1 ┃2 ┃3 ┃
                   a+1  ┣━╋━╋━╋━┫
              (1008)─→┃4 ┃5 ┃6 ┃7 ┃
                   a+2  ┣━╋━╋━╋━┫
              (1016)─→┃8 ┃9 ┃10┃11┃
                        ┗━┻━┻━┻━┛
                              圖6.

    既然我們把a[0], a[1], a[2]看成是一維數(shù)組名, 可以認為它們分別代表它們所對應的數(shù)組的首地址, 也就是講, a[0]代表第
0 行中第 0 列元素的地址, 即&a[0][0], a[1]是第1行中第0列元素的地址, 即&a[1][0], 根據(jù)地址運算規(guī)則, a[0]+1即代表第
0 行第1列元素的地址, 即&a[0][1], 一般而言,a[i]+j即代表第i行第j列元素的地址, 即&a[i][j]。
    另外, 在二維數(shù)組中, 我們還可用指針的形式來表示各元素的地址。如前所述, a[0]與*(a+0)等價, a[1]與*(a+1)等價, 因此
a[i]+j就與*(a+i)+j等價, 它表示數(shù)組元素a[i][j]的地址。
    因此, 二維數(shù)組元素a[i][j]可表示成*(a[i]+j)或*(*(a+i)+j),  它們都與a[i][j]等價, 或者還可寫成(*(a+i))[j]。
    另外, 要補充說明一下, 如果你編寫一個程序輸出打印a和*a,  你可發(fā)現(xiàn)它們的值是相同的, 這是為什么呢? 我們可這樣來理
解: 首先, 為了說明問題, 我們把二維數(shù)組人為地看成由三個數(shù)組元素a[0],a[1],a[2]組成, 將a[0],a[1],a[2]看成是數(shù)組名它們
又分別是由4個元素組成的一維數(shù)組。因此, a表示數(shù)組第0行的地址, 而*a 即為a[0], 它是數(shù)組名, 當然還是地址, 它就是數(shù)組第
0 行第0列元素的地址。

    2.2.2 指向一個由n個元素所組成的數(shù)組指針
    在Turbo C中, 可定義如下的指針變量:

      int (*p)[3];

    指針p為指向一個由3個元素所組成的整型數(shù)組指針。在定義中, 圓括號是不能少的, 否則它是指針數(shù)組, 這將在后面介紹。這
種數(shù)組的指針不同于前面介紹的整型指針, 當整型指針指向一個整型數(shù)組的元素時, 進行指針(地址)加1運算, 表示指向數(shù)組的下一
個元素, 此時地址值增加了2(因為放大因子為2), 而如上所定義的指向一個由3個元素組成的數(shù)組指針, 進行地址加1運算時, 其地
址值增加了6(放大因子為2x3=6), 這種數(shù)組指針在Turbo C中用得較少,  但在處理二維數(shù)組時, 還是很方便的。
例如:
          int a[3][4], (*p)[4];
          p=a;
    開始時p指向二維數(shù)組第0行, 當進行p+1運算時, 根據(jù)地址運算規(guī)則, 此時放大因子為4x2=8, 所以此時正好指向二維數(shù)組的第
1 行。和二維數(shù)組元素地址計算的規(guī)則一樣, *p+1指向a[0][1],*(p+i)+j則指向數(shù)組元素a[i][j]。
     例1
     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指向二維數(shù)組的第1行, 此時*b[0]或**b是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<2; i++) {
           b=a+i;                  /* 修改b的指向,  每次跳過二維數(shù)組的一行 */
           printf("%d\t",*(b[i]+1));
        }
         printf ("\n");
     }
    程序運行結果如下:
     9    13   17   21
     3    11   19

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

        ┏━━━┓     ┏━┳━┳━┳━┳━┳━┳━┳━┳━┓
        ┃    ─╂─→ ┃a ┃  ┃s ┃t ┃r ┃i ┃n ┃g ┃\0┃
        ┗━━━┛     ┗━┻━┻━┻━┻━┻━┻━┻━┻━┛
                              圖7.

以后我們可通過cp來訪問這一存貯區(qū)域, 如*cp或cp[0]就是字符a, 而cp[i]或*(cp+i)就相當于字符串的第i號字符, 但企圖通過指
針來修改字符串常量的行為是沒有意義的。

    4. 指針數(shù)組
    因為指針是變量, 因此可設想用指向同一數(shù)據(jù)類型的指針來構成一個數(shù)組, 這就是指針數(shù)組。數(shù)組中的每個元素都是指針變量,
根據(jù)數(shù)組的定義, 指針數(shù)組中每個元素都為指向同一數(shù)據(jù)類型的指針。指針數(shù)組的定義格式為:

     類型標識 *數(shù)組名[整型常量表達式];

    例如:
       int *a[10];

定義了一個指針數(shù)組, 數(shù)組中的每個元素都是指向整型量的指針, 該數(shù)組由10個元素組成,即a[0], a[1], a[2], ..., a[9], 它們
均為指針變量。a為該指針數(shù)組名, 和數(shù)組一樣, a是常量, 不能對它進行增量運算。a為指針數(shù)組元素a[0]的地址, a+i為a[i]的地
址, *a就是a[0], *(a+i)就是a[i]。
    為什么要定義和使用指針數(shù)組呢? 主要是由于指針數(shù)組對處理字符串提供了更大的方便和靈活, 使用二維數(shù)組對處理長度不等
的正文效率低, 而指針數(shù)組由于其中每個元素都為指針變量, 因此通過地址運算來操作正文行是十分方便的。
    指針數(shù)組和一般數(shù)組一樣, 允許指針數(shù)組在定義時初始化, 但由于指針數(shù)組的每個元素是指針變量, 它只能存放地址, 所以對
指向字符串的指針數(shù)組在說明賦初值時, 是把存放字符串的首地址賦給指針數(shù)組的對應元素, 例如下面是一個書寫函數(shù)
month_name(n), 此函數(shù)返回一個指向包含第n月名字的字符指針( 關于函數(shù), 第6節(jié)將專門介紹 )。

    例2: 打印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));

     }
  • 上一篇: 學C51的基礎 10《 聯(lián) 合(union) 》作者[cmh]©
  • 下一篇: 學C51的基礎 8 《 控制流程語句 》 作者[cmh]©
  • 發(fā)表評論   告訴好友   打印此文  收藏此頁  關閉窗口  返回頂部
    熱點文章
     
    推薦文章
     
    相關文章
    網(wǎng)友評論:(只顯示最新5條。)
    關于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機電之家 | 會員助手 | 免費鏈接

    點擊這里給我發(fā)消息66821730(技術支持)點擊這里給我發(fā)消息66821730(廣告投放) 點擊這里給我發(fā)消息41031197(編輯) 點擊這里給我發(fā)消息58733127(審核)
    本站提供的機電設備,機電供求等信息由機電企業(yè)自行提供,該企業(yè)負責信息內容的真實性、準確性和合法性。
    機電之家對此不承擔任何保證責任,有侵犯您利益的地方請聯(lián)系機電之家,機電之家將及時作出處理。
    Copyright 2007 機電之家 Inc All Rights Reserved.機電之家-由機電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術支持

    主辦:杭州市高新區(qū)(濱江)機電一體化學會
    中國行業(yè)電子商務100強網(wǎng)站

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1