是否可以通过引用第 n+1 个元素找到数组末尾的地址?

Is it possible to find the address of the end of an array with a reference to the n+1th element?

我需要知道指针何时穿过整个数组 -> 位于它后面的第一个位置。 c:

中的示例代码
unsigned int ar[10];
char *pointer = (char*) ar;
while(pointer != (char*) &ar[10]){
*pointer++ = 0xff
}

此示例是否可以将数组的每个元素设置为 0xffffffff?

原理是对的,但是你忘了初始化指针,在错误的地方递增。而是使用

unsigned int ar[10];
unsigned char *pointer = (unsigned char *)ar;
unsigned char *end = (unsigned char *)&ar[10];
while (pointer != end) { 
    *pointer++ = 0xff;
}

如果您在比较中递增指针,那么您将不会设置第一个字节,并且会写入超过限制的一个字节。

但永远不要重新发明轮子。 <string.h> 中有一个函数:

unsigned int ar[10];
memset(ar, 0xff, 10 * sizeof (int));

// or if a static array,
memset(ar, 0xff, sizeof ar);

另一方面,如果您真的想将 unsigned int 设置为 UINT_MAX,那么您可以明确:

for (size_t i = 0; i < 10; i++) {
    ar[i] = UINT_MAX; // or you could use `-1` as well, as it is guaranteed to result in `UINT_MAX` after conversion.
}

使用原始二进制文件时,我建议使用无符号字符类型,例如 uint8_t 而不是 char,因为后者具有 implementation-defined 符号。

然后你可以利用 C 中的两个特殊规则:

C11 6.3.2.3/7

When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.

这允许我们使用字符指针检查或修改 C 中任何类型的原始二进制内容。所以你确实可以使用字符指针将整数数组的每个字节设置为 0xFF。

另一个特殊规则隐藏在加法运算符的工作方式中,因为 [] 运算符只是 + 和取消引用的语法糖。 C11 6.5.6/8,强调我的:

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

这允许我们检查数组末尾之外的地址 1 int

但是 在字符类型指针和 int 指针之间转换会产生未对齐的指针,这(至少在理论上)会调用未定义的行为和可能的指令陷阱。所以你不能只是将字符指针转换为整数指针并进行比较。

所以完全正确的方法是将字符指针增加 sizeof(int) 然后在循环中每圈设置 4 个字节。

意味着以下是设置数组中所有字节的well-defined(但很麻烦&hard-to-read)方式:

#include <stdio.h>
#include <stdint.h>

int main (void)
{
  unsigned int arr[10];
  
  for(uint8_t* i = (uint8_t*)arr; (unsigned int*)i != &arr[10]; i+=sizeof(unsigned int))
  {
    i[0] = 0xFF;
    i[1] = 0xFF;
    i[2] = 0xFF;
    i[3] = 0xFF;
  }
  
  for(size_t i=0; i<10; i++)
  {
    printf("%X\n", arr[i]);
  }

  return 0;
}