簡體   English   中英

從二維數組分配指針

[英]Assigning pointer from two-dimensional array

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

int main(void)
{
    int ar[2][2] = {1,2,3,4};
    int **p= NULL , i=0, j=0;

    p = ar;             //compiler error. Confused ! Do i need to assign &a or anything. 

    puts("OUT: ");

    for(i = 0; i < 2; i++)
    {
        for(j = 0 ; j < 2; j++)
        {
            printf("%2d", *(*(ar + i) +  j));
            printf("%2d", *(*(p + i) + j)); /* This is wrong . Compiler error */
        }
    }
    exit(0);
}

我想創建一個指向2D數組的指針,這樣我應該能夠將p代替for循環中的ar 我糊塗了。 我知道訪問2d元素的其他方法,但我對此示例感到困惑。

在第一種情況下,您具有int[2]數組,而在第二種情況下,您具有int *數組。

如果使用sizeof(ar[0]) ,它將打印2*sizeof(int) ,而第二個將打印sizeof(int*)

  printf("sizeof(ar)       = %zu\n", sizeof(ar));
  printf("sizeof(ar[0])    = %zu\n", sizeof(ar[0]));
  printf("sizeof(ar[0][0]) = %zu\n", sizeof(ar[0][0]));
  printf("sizeof(p)        = %zu\n", sizeof(p));
  printf("sizeof(*p)       = %zu\n", sizeof(*p));
  printf("sizeof(**p)      = %zu\n", sizeof(**p));

由於我嘗試過編寫代碼,因此用p = ar替換p = a我只有這些錯誤:

$ gcc -Wall foobar.c 
foobar.c: In function ‘main’:
foobar.c:6:3: warning: missing braces around initializer [-Wmissing-braces]
foobar.c:6:3: warning: (near initialization for ‘ar[0]’) [-Wmissing-braces]
foobar.c:12:5: warning: assignment from incompatible pointer type [enabled by default]
foobar.c:21:7: warning: too many arguments for format [-Wformat-extra-args]

它也失敗了:

$ ./a.out 
sizeof(ar)       = 16
sizeof(ar[0])    = 8
sizeof(ar[0][0]) = 4
sizeof(p)        = 8
sizeof(*p)       = 8
sizeof(**p)      = 4
OUT: 
Segmentation fault

假設p的定義不太明確,這是正常的。

ar[2][2]不會分解為指針int **p=ar //is wrong指針,它將分解為第一行的Pointer(如果我們以矩陣形式考慮,我認為這很容易),這意味着在您的示例中,二維數組由2行組成,每行具有2個整數(列)。

因此ar將被分解為指向2個整數的指針,可以通過編程將其聲明為

int (*p)[2]; //this is pointer to 2 ints
int (*p)[3]; //this is pointer to 3 ints,if your array was declared like this ar[2][3]

因此,在您的程序中,您需要將int **p=NULL更改為int (*p)[2];

當我們說一個指向2個整數的指針時,這意味着當您(ex:- p+1) for above example添加一個(ex:- p+1) for above example它將指向2-d數組的下兩個整數(表示下一行)。

引用comp.lang.c常見問題列表中的問題6.18

數組遞歸為指針的規則(請參閱問題6.3)不是遞歸應用的。 (一旦應用規則一次,結果就是該規則不再適用的指針。)數組數組(即C中的二維數組)衰減為指向數組的指針,而不是指向a的指針。指針。


int **int [2][2]不兼容。 您應該將ar數組視為包含另一個數組的數組。 在堆棧上分配的多維數組連續存儲在內存中。

語句int ar[2][2]將由編譯器更改為int (*ar)[2] 注意括號的位置。 這是由於運算符的優先級:

  • ()運算符的優先級高於[]運算符
  • []運算符的優先級高於*運算符。

因此,如果您忽略它們,則:

int *ar[2];  // ar is an array of length 2 that holds pointers to ints.
int (*ar)[2];  // ar is a pointer to array of length 2 that hold ints.

您可以通過以下方式解決問題:

  • 改變int **p = NULL; 轉換為int (*p)[2];
  • int ar[2][2]更改為int **ar ,然后使用malloc()為行和列正確分配內存

想想二維數組如何下標。 例如,以下語句:

printf("%2d ", *(*(ar + 1) +  1));  // print the ar[1][1]

ar指針上加1 ,它指向int [2] 將8個字節添加到數組開頭的地址,然后在取消引用后添加1將僅添加4個字節,因為它現在指向int。

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

int main(void)   
{    
    const int row=4, col=4;
    int ar[row][col] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    int **p= NULL ; 
    int *np =  &ar[0][0];            
    p = &np;

    for(int i = 0; i < row; i++)
    {
       for(int j = 0 ; j < col; j++)
       {
            printf("address of a[%d][%d] is %x\n",i,j,&ar[i][j]);
            printf("%2d\n", *(*(ar + i) +  j));
            printf("%2d\n", *(*(p)+ i*col  + j));
       }
    }

    _getch();
    exit(0);
}

我這樣嘗試過,它對我有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM