简体   繁体   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);
}

I want to create a pointer to the 2D array so that instead of ar in the for loop i should be able to put p . 我想创建一个指向2D数组的指针,这样我应该能够将p代替for循环中的ar I'm confused. 我糊涂了。 I know other methods of accessing 2d elements but i'm confused with this example. 我知道访问2d元素的其他方法,但我对此示例感到困惑。

In the first case you have an array of int[2] , while in the second case you have an array of int*. 在第一种情况下,您具有int[2]数组,而在第二种情况下,您具有int *数组。

If you use sizeof(ar[0]) , it would print 2*sizeof(int) , while the second would print sizeof(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));

Since I tried you code, replaced p = a with p = ar I only have these errors: 由于我尝试过编写代码,因此用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]

And it fails too: 它也失败了:

$ ./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

Which is normal, assuming p is not so well defined. 假设p的定义不太明确,这是正常的。

ar[2][2] will NOT decompose into pointer to pointer int **p=ar //is wrong ,It will be decomposed into Pointer to first row(if we think in matrix form, which i think its easy),this means in your example your 2-d array consists of 2 rows,Each row has 2 integers(columns). ar[2][2]不会分解为指针int **p=ar //is wrong指针,它将分解为第一行的Pointer(如果我们以矩阵形式考虑,我认为这很容易),这意味着在您的示例中,二维数组由2行组成,每行具有2个整数(列)。

Hence ar will be decomposed into pointer to 2 integers, Which can be programmatically declared as 因此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]

So in your program you need to change int **p=NULL to int (*p)[2]; 因此,在您的程序中,您需要将int **p=NULL更改为int (*p)[2];

When we say a pointer to 2 integers,it means that When you add one (ex:- p+1) for above example then this will point to the next two integers of 2-d array(which means next row). 当我们说一个指向2个整数的指针时,这意味着当您(ex:- p+1) for above example添加一个(ex:- p+1) for above example它将指向2-d数组的下两个整数(表示下一行)。

a quote from comp.lang.c FAQ list, Question 6.18 引用comp.lang.c常见问题列表中的问题6.18

The rule (see question 6.3) by which arrays decay into pointers is not applied recursively. 数组递归为指针的规则(请参阅问题6.3)不是递归应用的。 (Once the rule has been applied once, the result is a pointer to which the rule no longer applies.) An array of arrays (ie a two-dimensional array in C) decays into a pointer to an array, not a pointer to a pointer. (一旦应用规则一次,结果就是该规则不再适用的指针。)数组数组(即C中的二维数组)衰减为指向数组的指针,而不是指向a的指针。指针。


int ** and int [2][2] are not compatible. int **int [2][2]不兼容。 you should think of your ar array as of an array that holds another arrays. 您应该将ar数组视为包含另一个数组的数组。 multidimensional arrays allocated on stack are stored in memory continguously. 在堆栈上分配的多维数组连续存储在内存中。

statement int ar[2][2] will be changed by the compiler to int (*ar)[2] . 语句int ar[2][2]将由编译器更改为int (*ar)[2] notice the placement of parentheses. 注意括号的位置。 this is because of operators precedence: 这是由于运算符的优先级:

  • () operator has higher precendece than [] operator ()运算符的优先级高于[]运算符
  • [] operator has higher precedence than * operator. []运算符的优先级高于*运算符。

. so if you would omit them, then: 因此,如果您忽略它们,则:

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.

you can resolve your problem by: 您可以通过以下方式解决问题:

  • changing int **p = NULL; 改变int **p = NULL; to int (*p)[2]; 转换为int (*p)[2];
  • changing int ar[2][2] to int **ar and then properly allocate memory for rows and columns using malloc() int ar[2][2]更改为int **ar ,然后使用malloc()为行和列正确分配内存

think of how that 2d array is subscripted. 想想二维数组如何下标。 for example, the statement: 例如,以下语句:

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

adds 1 to ar pointer, which points to int [2] . ar指针上加1 ,它指向int [2] 8 bytes are added to the address of beginning of array, then after dereference adding 1 will add only 4 bytes, since it refers now to int. 将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);
}

i tried like this, it worked for me. 我这样尝试过,它对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM