二维数组和指针

发布于 2024-12-23 11:40:40 字数 635 浏览 5 评论 0原文

我有以下代码片段:

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. 据我所知,板(即)数组名称代表地址第一个子数组(即)board[0]

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

为什么我在所有 printf()< 中得到相同的地址/code> 语句?我希望这两个语句有不同的地址。

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

I have the following code snippet:

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]);

Both printf() statements all print the same value: 0x0013ff67

  1. As per my knowledge, board (i.e) array name represents the address of the first subarray (i.e) board[0] and

  2. board[0] represents the address of first element in the first array (i.e) board[0][0]

Why am I getting the same address in all my printf() statements? I expect different addresses for both statements.

I am pretty new to this stuff and don't understand this behavior. Kindly enlighten me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一口甜 2024-12-30 11:40:40

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

Though it's a 2D array, inside the memory it will be represented as linear array. so when you say, board[0][0] it still points to the first element in that linear array and hence the same memory address.

和我恋爱吧 2024-12-30 11:40:40

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

As per my knowledge, board (i.e) array name represents the address of the first subarray (i.e) board[0]

This is only true if board is used outside of these contexts

  • As operand of the & operator
  • As operand of sizeof

When any of that applies, expression board represents the array and keeps having the type of the array (char[3][3]). Applying the & operator to it results in getting the address of the array, which of course equals the address of its first element, merely having a different type (char(*)[3][3] instead of char(*)[3]). The same that is true about the array board is true about its first sub array board[0].

When you use it outside of those contexts, you get the address of the first element (subarray in your case). That address is not an object but just a value. Value have no address, but objects have. Trying to apply & on it would fail. For example

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

Note that anything said above applies to C; not necessarily to C++.

傲影 2024-12-30 11:40:40

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

int **ptr;

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

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

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

Of course this will print the same address.
Think about 2D arrays like this for a minute,

int **ptr;

The address *ptr does equal &(**ptr).

Because basically, that's what your code is doing.

and remember that in memory, 2D arrays will be mapped linearly.

失眠症患者 2024-12-30 11:40:40

可能的情况是,您已经了解 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] (或)*board[0] (或)**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

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

It may be the case that you know an object-oriented language such as Java or Python, and now you are learning the C language. The difference between Java and C when thinking about char board[3][3] is that in C the board variable is represented in memory as 9 characters at adjacent memory addresses. Like so:

board: 1 2 3 4 5 6 7 8 9

In C, &board yields the same memory address as &board[0] and &board[0][0].

In contrast to this, in Java the variable would be declared as char[][] board and its memory representation would conceptually look like this:

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

where ptr(x) points to memory address of x. So, in Java, board points to a different memory address than board[0].


You say In C, &board yields the same memory address as &board[0] and &board[0][0]. But i am able to access the first element only via board[0][0] (or) *board[0] (or) **board. Why is it so??

Although the expressions &board and &board[0] and &board[0][0] yield the same address, the type system of the C language is preventing you from accessing the char value. In a C compiler, the types are (conceptually):

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

Assuming a variable of type char, we can write:

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

but cannot write:

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

because the type on the left side is incompatible with the type on the right side of the assignment.

If you are sure that an address points to a char, you can use a type cast:

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

The downside is that such type casts may lead to coding bugs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文