简体   繁体   English

带有二维数组的指针

[英]Pointers with two dimensional array

Please consider the following piece of code请考虑以下代码

#include <stdio.h>
#define ROW_SIZE 2
#define COL_SIZE 2

int main()
{
   int a[ROW_SIZE][COL_SIZE]={{1,2},{3,4}};

   // Base address:Pointer to the first element a 1D array
   printf("Base address of array:%p\n",a);

   //The value at the base address: should be the address of 1st 1D array
   printf("Value at the Base address:%p\n",*a);

   return 0;
}

Output obtained:获得的输出:

Sample Output:
Base address of array:0xbff77434
Value at the Base address:0xbff77434

Somehow, I am failing to understand the concept of the base address of a 2D array and the value at the base address which is inturn an address to a 1D array being same.不知何故,我无法理解二维数组的基地址的概念和基地址处的值,而基地址又是一维数组的地址。 Please explain.请解释。

Arrays aren't pointers, and in C, a multidimensional array is just an array of arrays.数组不是指针,在 C 中,多维数组只是数组的数组。 In many contexts, using the name of an array "decays" into a pointer to the first element of that array.在许多情况下,使用数组的名称“衰减”为指向该数组第一个元素的指针。 That's what happens in both of your print statements.这就是您的两个打印语句中发生的情况。 In the first case:在第一种情况下:

printf("Base address of array:%p\n",a);

a becomes a pointer to the first element of the array - that is, a pointer to the first row of your array. a成为指向数组第一个元素的指针 - 即指向数组第一行的指针。 In your case, that means you get a pointer of type int (*)[2] .在你的情况下,这意味着你得到一个int (*)[2]类型的指针。

In the second case:在第二种情况下:

printf("Value at the Base address:%p\n",*a);

The same decaying happens, but then you dereference that pointer.发生相同的衰减,但随后您取消引用该指针。 That means you dereferenced that int (*)[2] pointer to the first row, leaving you with an array again (the first row).这意味着您取消了指向第一行的int (*)[2]指针的引用,再次为您留下一个数组(第一行)。 That array itself decays into a pointer to its first element, giving you a resulting int * pointer (to the first element of the first row).该数组本身衰减为指向第一个元素的指针,从而为您提供一个结果int *指针(指向第一行的第一个元素)。

In both cases the address is the same, since that's how the array is laid out in memory.在这两种情况下,地址是相同的,因为这就是数组在内存中的布局方式。 If we said your 2D array started at address 0 , it would look like this (assuming a 4 byte int type):如果我们说你的二维数组从地址0开始,它看起来像这样(假设是一个 4 字节的int类型):

 Address       Value
    0            1
    4            2
    8            3
   12            4

The address of the first row and the address of the first element of the first row are both 0 .第一行的地址和第一行的第一个元素的地址都是0

Re-structuring the diagram in the question and consolidating the information from previous answers, I am creating the following answer.重新构建问题中的图表并整合先前答案中的信息,我正在创建以下答案。

数组和指针

One dimensional array一维数组

  • Consider an array a of 4 integers as a[4]将 4 个整数的数组 a 视为a[4]
  • Basic rule is both a and &a will point to same location.But they aren't pointing to the same type.基本规则是a&a都指向相同的位置。但它们指向相同的类型。
  • &a will point to the entire array which is an int[] . &a将指向整个数组,它是一个int[] The pointer type is int(*)[]指针类型为int(*)[]
  • a , when it decays to a pointer, will point to the first element of the array which is an int . a ,当它衰减到一个指针时,将指向数组的第一个元素,它是一个int The pointer type is int *指针类型为int *

Two dimensional array二维数组

  • Consider an array containing two 1D arrays, with each of them having two elements ;考虑一个包含两个一维数组的数组,每个数组都有两个元素; a[2][2] . a[2][2]
  • Since the number of dimensions increases, we have one more level of hierarchy ie &a , a and *a will point to same location, but they aren't pointing to the same type.由于维数增加,我们多了一层层次结构,即&aa*a将指向相同的位置,但它们指向相同的类型。
  • &a will point to the entire array which is int[][] . &a将指向整个数组,即int[][] The pointer type is int(*)[][] .指针类型是int(*)[][]
  • a , when it decays to a pointer, will point to the first element of the 2D array which is an int[] . a ,当它衰减为指针时,将指向二维数组的第一个元素,即int[] The pointer type is int(*)[]指针类型为int(*)[]
  • By using *a , we are de-referencing the pointer to a 1D array.通过使用*a ,我们取消了指向一维数组的指针的引用。 Hence we will have a int * pointing to the first integer value of the 2D array.因此,我们将有一个int *指向二维数组的第一个整数值。

I think the formatting of your output is throwing you.我认为你的输出格式让你失望。 You are right, the address of the first array element (0xbff77434) is different from the value (1).你是正确的,第一个数组元素(0xbff77434)的地址从所述值(1)不同。 The %p is getting confused trying to force both to a "pointer" format. %p 试图将两者强制为“指针”格式时感到困惑。

And yes, Carl's correct too.是的,卡尔也是正确的。

If you want to see what's at the first element, you would say any of these:如果你想看到的第一个元素是什么,你会说任何这些:

printf("%i", a[0][0]);

int* p = &a[0][0];    // point 'p' to the beginning of 'a'
// (or)
int* p = a;           // saying "&a[0][0]" is the same as saying "a"
printf("%i", *p);     // here, the dereference is what you want

As far as 1D vs 2D arrays, it's just a matter of interpretation.就 1D 与 2D 数组而言,这只是一个解释问题。 Both两个都

int x[4];

and

int x[2][2];

create contiguous blocks of 4 'int-sized' elements.创建 4 个“整型”元素的连续块。 And in both cases, the expression 'x' refers to the address of the 0th entry (eg, the address of the array).并且在这两种情况下,表达式“x”指的是第 0 个条目的地址(例如,数组的地址)。

The bidimensional array a[2][2] can be seen as a monodimensional array with 4 elements.二维数组a[2][2]可以看作是一个有 4 个元素的单维数组。 Think what happens when you cast a to an int* pointer:想想当你将a转换为int*指针时会发生什么:

int a[2][2] = {{ 1, 2 }, { 3, 4 }};
int* p = (int*) a; // == { 1, 2, 3, 4 }

assert(a[1][0] == p[2] == 3); // true

int* a0 = a[0];  // the first row in the bidimensional array
int* p0 = &p[0]; // the first element in the monodimensional array

assert(*a0 == *p0 == 1); // true

// Or the long version:
assert(a[0][0] == *a0 == a0[0] == p[0] == *p0 == p0[0] == 1); // true

// And for the second array in a:
int* a1 = a[1]; // the second row in the bidimensional array
int p2 = &p[2]; // the third element in the monodimensional array

assert(a[1][0] == *a1 == a1[0] == p[2] == *p2 == p2[0] == 3); // true

The arrays a and a[0] basically point to the same address, but their types convey informations about how they can be manipulated.数组aa[0]基本上指向相同的地址,但它们的类型传达了有关如何操作它们的信息。

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

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