c - 二维数组地址 - 数组指针的使用




将数组指针增加到最后一项之外 (4)

C不检查数组边界。 因此,即使您访问的数组超出了声明的大小,它也不会出现任何错误。 根据我的回答,您的问题:

  1. 没有数字纯粹是垃圾值。
  2. 最后一个数字可以是任何数字(垃圾内容包括零)。 根据ISO C标准,它称为未定义行为。
  3. 不,不应该! 但是C是当时编译器运行缓慢的语言,即使在Assembly中保存3-4条指令也很重要!

我在C编程和数组指针方面玩得很开心。

当我将数组指针超出数组大小时,有人可以解释发生了什么吗?

看起来我正在访问数组之后的存储单元,但我只是想确定一下。

  1. 这些数字有什么意思吗?
  2. 为什么最后一个数字为零?
  3. 程序应该能够访问尚未分配的内存吗?

这么多的问题!

int arr[] = { 1, 2, 3, 4, 5 };
int *xPtr = arr;

for(int i = 0; i < 10; i++) {
    printf("current pointer is %d\n", *xPtr++);
}

结果是:

current pointer is 1
current pointer is 2
current pointer is 3
current pointer is 4
current pointer is 5
current pointer is 0
current pointer is 127926431
current pointer is -759946469
current pointer is -492049712
current pointer is 32766

这是我发现正确遍历数组的唯一方法。 这个对吗?

int arraySize = sizeof(arr) / sizeof(int);
for(int i = 0; i < arraySize; i++) {
    printf("current pointer is %d\n", *xPtr++);
}

结果是:

current pointer is 1
current pointer is 2
current pointer is 3
current pointer is 4
current pointer is 5

它取决于声明数组的位置(更确切地说是数组的存储位置)。 如果您将没有初始化的任何类型的数组声明为全局或静态,则默认情况下它将初始化为零;否则,默认为0。 否则,如果您在任何函数中声明它,即在没有初始化的情况下自动进行,则它将包含垃圾值。 在程序的此处,当访问超出数组范围的内存中的位置时,程序获得的值是垃圾值。 因为默认情况下,每个内存位置都包含垃圾值。 初始化数组时,将为内存块分配您提供的值。 第二件事是没有最好的迭代数组。 这完全取决于你。

在增加指针时,指针将增加其指向的对象的大小,指向数组中的下一个元素。 例如:

data_type  arr[10];

指针的增量将通过sizeof(data_type)进行。 在C语言中,访问未分配的内存可能会引发异常/警告。


您需要了解指针增量 *xPtr++ 通过增加它所指向的对象的大小来工作。 在您是 int 的情况下,每个操作都会根据系统中 int 的大小来增加 sizeof(int)

由于数组只有5个元素,因此在具有4字节 int 的计算机上,您不能将其增加超过5个计数。 除此之外,您正在访问未为该数组分配的内存,并且从那些位置访问该值会调用未定义的行为。

您的第二种方法似乎是正确的,通过简单的修复即可使用从 intsize_tsizeof() 返回类型,尽管赋值时会发生隐式转换

size_t arraySize = sizeof(arr) / sizeof(int);
for(size_t i = 0; i < arraySize; i++) {
    printf("current pointer %p and value is %d\n", (void*)xPtr, *xPtr++);
}

是的,当您将指针增加到数组的大小之外时,可以访问数组之后的内存。 它将仅包含任何称为 垃圾 值的随机值。

这些垃圾值在您的程序中没有用,您应该避免使用下面的for循环访问它,如您的答案中所述:

int arraySize = sizeof(arr) / sizeof(int);
for(int i = 0; i < arraySize; i++)
{ 
      printf("current pointer is %d\n", *xPtr++); 
}

这些值没有任何意义。 它们只是在您访问它之前已经存储在该特定内存位置中的值。

让我为您讲一个例子。 考虑一个2D数组和一个指向它的指针

int a[2][2];
int *p = &a[0][0];

现在,仔细看一下索引。 如果尝试 p+0 ,它将指向 a[0][0]p+1 将指向 a[0][1] 。 但是,如果现在尝试 p+2 ,它将指向 a[1][0] 因为这只是下一个存储位置。

并且,除了 p+3p+4 所有值都是垃圾。





pointers