C語言 二維數組與指針筆記

今天分析了C語言二維數組和指針的基本理解,感受有點懵。。。代碼記錄一下,若是有大神臨幸發現哪裏有誤,歡迎指正~~~數組

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//void func(int p[][])  //這樣寫等同於void func(int **p)   p++移動了四個字節,(*p)++移動了四個字節,不符合二維數組規律
//{
//}


//列優先輸出的函數(即豎着輸出)
void func(int p[][4], int a, int b)  //這樣寫是正確的,這樣寫等同於void func(int (*p)[4])   p++移動16個字節,(*p)++移動了4個字節,a和b是爲了保持維度,a表示列,b表示行
{
    for (int i = 0; i < a; i++)
    {
        for (int j = 0; j < b; j++)
        {
            printf("%d\n", *(*(p + j) + i));
        }
    }
}

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

    //printf("%d\n", sizeof(array[0]));  // 結果爲16,媽的,array[0]居然不是指針,而是一個數組的名稱,
    //printf("%d\n", sizeof(array));    //結果48
 func(array, 
sizeof(array[0]) / sizeof(int), sizeof(array) / sizeof(array[0]));//
第二個參數是列數,第三個參數爲行數
//array[0]並非一個變量,是二維數組中第0行的首地址
//和下面的:      *(p + 0) + 1;    表明int *向後位移了一個位置   道理上應該是相同的。

        //在二維數組中*array表明的也是數組的首地址,而一維數組中*array表明的是第一個元素的值
    //printf("%d %d %d %d\n", array, *array, &array, &array[0][0], array[0]);

   //
printf("%d\n", array + 1); //
printf("%d\n", array[0] + 1);
        //結果爲array + 1  移動了16個字節
        //        array[0] + 1 移動了4個字節
        //能夠這樣理解,array + 1當作連長,array[0] + 1當作排長,連長每次走一行(即走4個數,14個字節),排長每次走一列(即走一個數,4個字節)


    //int *p = array;  //指向一維數組的指針

   
//int (*p)[4];
是一個變相的二級指針
    //p = array;
    //*(p + 0) + 1;    表明int *向後位移了一個位置

    //for (int i = 0; i < 4; i++)
    //{
    //    for (int j = 0; j < 3; j++)
    //    {
    //        printf("%d\n", *(*(p + j) + i));
    //    }
    //}
    //*(p + 0)   表明的是指向第一行的指針。因此*(p + 0) + 1  是指向第一行第二個元素的位置
    //printf("---------------\n");

    //-----------
    //p + 1;   //表明的是排長,每次走一行
    //p[0][0] = *(*(p + 0) + 0);  //表明的是連長,每次走一個數

    //printf("%d\n", *(*(p+1)));  //第一行第0個元素

    system("pause");
    return 0;
}

 

分析以下:函數

黃色代碼部分:輸出的地址徹底相同,因此二維數組和一維數組的一點區別是:   在二維數組中*array表明的也是數組的首地址,而一維數組中*array表明的是第一個元素的值 測試

紅色代碼部分:      相對於黃色代碼部分,紅色代碼結果爲:     array + 1 移動了16個字節  , array[0] + 1 移動了4個字節;spa

  由於array是數組的首地址,並且是一個二維數組,因此array+1  應該是移動一行,即4個數字,array[0]是二維數組的「第一行數組」的首地址,因此+1應該是在第一行數組裏面移動指針;指針

( 若是 int  *p = &i;  那麼p+1的結果就會移動4個字節,若是 char  *p = &i;  那麼p+1的結果就會移動1個字節,  這裏其實也是相同的道理,只是很差理解。。。)code

也可使用排長和連長的例子來理解,把array當作連長,把array[0]當作排長,連長每次審閱,會一行一行的走,排長審閱,則會一排一排的走,因此array(連長)每次走16個字節,array[0]每次走4個字節。blog

 

 

橘黃色代碼部分:       定義二級指針的時候,通常會這樣定義,int (*p)[4]; get

這裏有一個「指針數組」和「數組指針」的概念,圖示和代碼以下:string

            指針數組:                                                                                    數組指針it

          int *p[5];                                                                           int (*P)[10];

ImageImage

#include <stdio.h>
#include <stdlib.h>

int main()
{
           //指針數組
           char *s[10];   //是一個數組,該數組中有10個char *指針,每一個指針指向一個字符
          printf( "%d\n" ,sizeof (s[0]));  //4

           //數組指針
           char (*s1)[10];    //是一個指針變量,該指針變量指向一個char[10];不能指向其餘任何char[n]數組
          printf( "%d\n" , sizeof (s1));   //4

          system( "pause" );
           return 0;
}

 

因此:int (*p)[4]; 是一個數組指針,指向一個4個元素的數組,

p = array;    也就是把二維數組的首地址賦給p,array也是一個地址(至關於一個指針,但若是咱們用sizeof(array)會發現其實不是一個指針),因此p實際上是一個變相的二級指針(你不信的話能夠利用**p測試看是否可以取到數組的第一個元素)

因此    *(p + 0) + 1; 表明int *向後位移了一個位置   也就不難理解了, p是一個二級指針, p+0表明的其實就是第一行數組的首地址。*(p+0) 仍是一個指針,  也就是一個int * 類型的變量(指針也是一個變量),*(p + 0) + 1;表明的就是int *向後位置了一個位置

 

*(p + 0) 表明的是指向第一行的指針。因此*(p + 0) + 1 是指向第一行第二個元素的位置的指針,*(*(p + 0) + 1 ) 就是第一行第二個元素的值;

 

灰色顏色代碼的部分:     這樣寫的緣由就是直接把二維數組的維度發過去,由於在接收端函數方是不知道二維數組的維度的,並且這樣寫之後更改數組的維度的時候,不用更改其餘代碼。

相關文章
相關標籤/搜索