我编写了一个C程序,用于使用指针显示数组的值。这是代码:
Capybara.page
正如您在终止循环后看到的那样,指针保存数组中值的内存地址。因为它没有初始化最后一个输出,所以它应该是垃圾值。但是,每次显示5是数组的大小。然后,我认为数组的已分配内存的下一个内存地址包含数组的大小。但是,双类型数组不会发生这种情况。
#include <stdio.h>
int main()
{
int a[] = {1, 1, 1, 1, 1};
int *ptr = a;
for (int i = 0 ; i < 5; i++)
printf("%d ", *ptr++);
printf("%d", *ptr);
}
有人会解释输出吗?
答案 0 :(得分:6)
这只是此地址中内存的值。您永远不应该访问未由您分配的内存(在这种情况下,您正在访问第6个元素,但您只声明了5个元素)。在某些情况下,这可能会导致分段错误。
答案 1 :(得分:3)
C不会在数组的开头或结尾处存储任何数组元数据(包括数组长度)。对于整数数组,输出的最可能的解释是变量i
使用的内存紧跟在数组的最后一个元素之后,如下所示:
+---+
a: | 1 | a[0]
+---+
| 1 | a[1]
+---+
| 1 | a[2]
+---+
| 1 | a[3]
+---+
| 1 | a[4]
+---+
i: | 5 | a[5]
+---+
但是,无法依赖此行为保持一致,正如您所看到的那样将数组类型更改为double
。
尝试读取元素末尾的元素中包含的值会导致未定义的行为。 Chapter and (truncated) verse:
6.5.6附加运营商
...
8当一个具有整数类型的表达式被添加到指针或从指针中减去时, result具有指针操作数的类型... 如果结果指向一个超过数组对象的最后一个元素的那个,那么 不得用作被评估的一元*
运算符的操作数。
对于咯咯笑,我在工作时在我的系统上编译了你的代码,我得到以下输出:
1 1 1 1 1 0
这实际上只是编译器如何为此特定程序在内存中放置对象的工件。
答案 2 :(得分:2)
你做的是调用未定义的行为。
这很简单,可能只是i
的值,打印i
的地址并检查。但要小心,它并不总是这样。只需在程序中声明一个新变量,它就可能会发生变化。
对于double
,它不起作用,因为数组后面的地址不再与i
的地址匹配。当我说小心时,这就是我的意思。