7

我有以下代码片段:

char board[3][3] = {
                     {'1','2','3'},
                     {'4','5','6'},
                     {'7','8','9'}
                   };

printf("address of board : %p\n", &board);
printf("address of board[0] : %p\n", &board[0]);

两个printf()语句都打印相同的值:0x0013ff67

  1. 据我所知,板(ie)数组名称代表第一个子数组(ie)的地址board[0]

  2. board[0]表示第一个数组中第一个元素的地址(即)board[0][0]

为什么我在所有printf()报表中都得到相同的地址?我希望这两种说法都有不同的地址。

我对这些东西很陌生,不理解这种行为。请赐教。

4

4 回答 4

5

虽然它是一个二维数组,但在内存中它将被表示为线性数组。因此,当您说 board[0][0] 时,它仍然指向该线性数组中的第一个元素,因此指向相同的内存地址。

于 2011-12-29T15:36:59.187 回答
1

当然,这将打印相同的地址。
想一想这样的二维数组,

诠释**ptr;


地址*ptr确实相等&(**ptr)

因为基本上,这就是您的代码正在做的事情。

请记住,在内存中,二维数组将被线性映射。

于 2011-12-29T16:25:18.740 回答
1

可能是您知道 Java 或 Python 等面向对象的语言,而现在您正在学习 C 语言。Java 和 C 的区别在于char board[3][3],在 C 中,board变量在内存中表示为相邻内存地址的 9 个字符。像这样:

board: 1 2 3 4 5 6 7 8 9

在 C 中,产生与和&board相同的内存地址。&board[0]&board[0][0]

与此相反,在 Java 中,变量将被声明为char[][] board,其内存表示在概念上如下所示:

board: ptr(A) ptr(B) ptr(C)
A:     1 2 3
B:     4 5 6
C:     7 8 9

whereptr(x)指向的内存地址x。因此,在 Java 中,board指向的内存地址与board[0].


你说在 C 中,&board 产生与 &board[0] 和 &board[0][0] 相同的内存地址。但我只能通过 board[0][0] (or) *board[0] (or) **board 访问第一个元素。为什么会这样??

尽管表达式&board&board[0]产生&board[0][0]相同的地址,但 C 语言的类型系统阻止您访问该char值。在 C 编译器中,类型是(概念上):

board:       type char[3][3]
board[0]:    type char[3]
board[0][0]: type char

假设一个类型为 的变量char,我们可以这样写:

char c;
c = board[0][0];

但不能写:

char c;
c = board;    // Error
c = board[0]; // Error

因为左边的类型与赋值右边的类型不兼容。

如果您确定地址指向 a char,则可以使用类型转换:

char c;
c = *(char*)board;    // Works OK
c = *(char*)board[0]; // Works OK

缺点是这种类型转换可能会导致编码错误。

于 2011-12-29T17:23:53.027 回答
1

据我所知,板(即)数组名称表示第一个子数组(即)板[0]的地址

board仅当在这些上下文之外使用时才适用

  • 作为运算符的&操作数
  • 作为操作数sizeof

当其中任何一个适用时,表达式board表示数组并保持数组的类型 ( char[3][3])。将&运算符应用于它会导致获取数组的地址,这当然等于它的第一个元素的地址,只是具有不同的类型(char(*)[3][3]而不是char(*)[3])。数组board的第一个子数组也是如此board[0]

当您在这些上下文之外使用它时,您将获得第一个元素的地址(在您的情况下为子数组)。该地址不是一个对象,而只是一个值。值没有地址,但对象有。试图申请&它会失败。例如

// error: trying to apply '&' on something that has no address
&(1 ? board : board)

请注意,上述任何内容都适用于 C;不一定是 C++。

于 2011-12-29T15:36:50.370 回答