从二维数组中指定指针

时间:2014-07-22 13:26:39

标签: c arrays pointers 2d

#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数组的指针,而不是ar循环中的for 我应该能够p。我很困惑。我知道访问2d的其他方法 元素,但我对这个例子感到困惑。

4 个答案:

答案 0 :(得分:0)

在第一种情况下,您有一个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 = a替换为p = ar我只有这些错误:

$ 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没有很好地定义。

答案 1 :(得分:0)

ar[2][2]不会分解为指向指针int **p=ar //is wrong的指针,它将被分解为指向第一行的指针(如果我们以矩阵形式思考,我认为这很容易),这意味着在你的例子中你的2-d数组由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时,这将指向2-d数组的下两个整数(这意味着下一行)。

答案 2 :(得分:0)

comp.lang.c FAQ list, Question 6.18

的引用
  

数组衰减为指针的规则(参见问题6.3)不是   递归地应用。 (一旦规则应用一次,结果   是规则不再适用的指针。)数组数组   (即C中的二维数组)衰变为指向数组的指针,   不是指向指针的指针。


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()
  • 为行和列正确分配内存

想一想如何下载2d数组。例如,声明:

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

1添加到ar指针,该指针指向int [2]。 8个字节被添加到数组开头的地址,然后在取消引用后添加1将只添加4个字节,因为它现在引用了int。

答案 3 :(得分:-1)

#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);
}

我试过这样,它对我有用。