首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >二维阵列问题

问二维阵列问题
EN

Stack Overflow用户
提问于 2012-09-21 11:20:19
回答 7查看 214关注 0票数 4

我用C编写了以下代码:

代码语言:javascript
复制
#include<stdio.h>

int  main()
{
  int a[10][10]={1};
  //------------------------
  printf("%d\n",&a);
  printf("%d\n",a);
  printf("%d\n",*a);
  //-------------------------
  printf("%d",**a);

  return 0;
}

对于上面的3个printf语句,我得到了相同的值。在我的机器上是2686384。但最后一份声明我得到了1份。

是不是出什么问题了?这些声明意味着:

  1. a的地址是2686384
  2. 存储在a中的值为2686384
  3. 存储在a指出的变量地址(即2686384)上的值是2686384。

这意味着a一定是一个指向自身的变量.

那么为什么*(*a) 1的输出呢?为什么它没有被评估为*(*a)=*(2686384)=2686384

EN

回答 7

Stack Overflow用户

发布于 2014-02-01 02:53:48

代码语言:javascript
复制
#include<stdio.h>

int  main()
{
  // a[row][col]
  int a[2][2]={ {9, 2}, {3, 4} };
  // in C, multidimensional arrays are really one dimensional, but
  // syntax alows us to access it as a two dimensional (like here).

  //------------------------
  printf("&a            = %d\n",&a);
  printf("a             = %d\n",a);
  printf("*a            = %d\n",*a);
  //-------------------------

  // Thing to have in mind here, that may be confusing is:
  // since we can access array values through 2 dimensions,
  // we need 2 stars(asterisk), right? Right.

  // So as a consistency in this aproach,
  // even if we are asking for first value,
  // we have to use 2 dimensional (we have a 2D array)
  // access syntax - 2 stars.

  printf("**a           = %d\n", **a );         // this says a[0][0] or *(*(a+0)+0)
  printf("**(a+1)       = %d\n", **(a+1) );     // a[1][0] or *(*(a+1)+0)
  printf("*(*(a+1)+1)   = %d\n", *(*(a+1)+1) ); // a[1][1] or *(*(a+1)+1)
  // a[1] gives us the value on that position,
  // since that value is pointer, &a[i] returns a pointer value
  printf("&a[1]         = %d\n", &a[1]);
  // When we add int to a pointer (eg. a+1),
  // really we are adding the lenth of a type
  // to which pointer is directing - here we go to the next element in an array.

  // In C, you can manipulate array variables practically like pointers.
  // Example: littleFunction(int [] arr) accepts pointers to int, and it works vice versa,
  //          littleFunction(int* arr) accepts array of int.

  int b = 8;
  printf("b             = %d\n", *&b);

  return 0;

}
票数 2
EN

Stack Overflow用户

发布于 2012-09-21 11:30:49

包含数组名称的表达式可以衰减为指向数组的第一个元素的指针。因此,即使a有int[10][10]类型,它也可能衰变到int(*)[10]。

现在,这种衰减发生在表达式*a中。因此,表达式具有int[10]类型。重复相同的逻辑,这再次衰变为int*,因此**a是一个int,而且它是数组a第一个元素的第一个元素,即1。

其他三个print语句分别打印数组的地址、数组的第一个元素和数组的第一个元素(当然,它们都是相同的地址,只是不同的类型)。

票数 1
EN

Stack Overflow用户

发布于 2012-09-21 11:55:46

首先,一个关于数组的词..。

除非是operand0的sizeof、_Alignof或一元&运算符,或者是用于初始化声明中的另一个数组的字符串文字,否则类型为“T的N元素数组”的表达式将被转换为“指向T的指针”类型的表达式,表达式的值将是数组中第一个元素的地址。

表达式&a的类型为“指向int的10元素数组的10元素数组的指针”,即int (*)[10][10]。表达式a的类型为“int的10元素数组的10元素数组”,根据上面的规则,该数组将衰减为“指向int的10元素数组的指针”或int (*)[10]。最后,表达式*a (等效于a[0])具有“int的10元素数组”类型,根据上面的规则,它再次衰变为“指向int的指针”。

这三个表达式都具有相同的值,因为数组的地址和第一个元素的地址是相同的:&a[0][0] == a[0] == *a == a == &a。但是,表达式的类型是不同的,这在执行指针算术时很重要。例如,如果我有以下声明:

代码语言:javascript
复制
int (*ap0)[10][10] = &a;
int (*ap1)[10]     =  a;
int *ip            = *a;

然后ap0++将ap0提前到指向下一个int的10x10数组,ap1++将ap1提前到指向下一个int (或a[1])的10元素数组,ip++将ip提前到指向下一个int (&a[0][1])。

**a等价于*a[0],而后者等价于a[0][0]。它是a的第一个元素的值,其类型为int和值1 (请注意,只有a[0][0]初始化为1;其余所有元素都初始化为0)。

请注意,应该使用%p打印指针值:

代码语言:javascript
复制
printf("&a = %p\n", &a);
printf(" a = %p\n",  a);
printf("*a = %p\n", *a);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12529484

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档