二维数组和指针
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 访问第一个元素。为什么会这样??以上是关于二维数组和指针的主要内容,如果未能解决你的问题,请参考以下文章