二维数组和指针

Posted

技术标签:

【中文标题】二维数组和指针【英文标题】:Two dimensional arrays and pointers 【发布时间】:2012-01-29 23:37:30 【问题描述】:

我有以下代码sn-p:

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

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

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

为什么我的所有printf() 语句中的地址都相同?我希望两个语句的地址不同。

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

据我所知,板(即)数组名称表示第一个子数组(即)板[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++。

【讨论】:

您好,感谢您的回复,我部分理解。您能否提供一个简单的示例程序来解释您的评论。我会很有帮助的。谢谢。 @intex 你的问题我将提供的简单示例程序。【参考方案3】:

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

int **ptr;

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

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

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

【讨论】:

【参考方案4】:

您可能知道 Java 或 Python 等面向对象的语言,而现在您正在学习 C 语言。在考虑 char board[3][3] 时,Java 和 C 之间的区别在于,在 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

其中ptr(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

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

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

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

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

【讨论】:

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

以上是关于二维数组和指针的主要内容,如果未能解决你的问题,请参考以下文章

c++二维数组和二级指针

C语言指针指向一维数组与二维数组?

C语言中二维数组名是否可以看作指针数组名?

c语言中如何通过二级指针来操作二维数组

怎么让一个二维指针指向一个二维数组

菜鸟求解用指针求二维数组各个元素和,请大侠帮忙!!!!!谢谢!!!!