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

Arrays 是否可以通过对n+的引用找到数组末尾的地址;第1元素?,arrays,c,pointers,array-pointer,Arrays,C,Pointers,Array Pointer,我需要知道指针什么时候穿过整个数组->在它后面的第一个位置。 c语言中的示例代码: unsigned int ar[10]; char *pointer = (char*) ar; while(pointer != (char*) &ar[10]){ *pointer++ = 0xff } 这个例子可以将数组的每个元素都设置为0xFFFFFF吗?原理是正确的,但是您忘记初始化指针,并且在错误的位置递增指针。宁可使用 unsigned int ar[10]; unsigned char

我需要知道指针什么时候穿过整个数组->在它后面的第一个位置。 c语言中的示例代码:

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

这个例子可以将数组的每个元素都设置为0xFFFFFF吗?

原理是正确的,但是您忘记初始化指针,并且在错误的位置递增指针。宁可使用

unsigned int ar[10];
unsigned char *pointer = (unsigned char *)ar;
unsigned char *end = (unsigned char *)&ar[10];
while (pointer != end) { 
    *pointer++ = 0xff;
}
如果在比较中增加指针,则不会设置第一个字节,而是写入超过限制的一个字节

但永远不要重新发明轮子。
中有一个函数用于:

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

// or if a static array,
memset(ar, 0xff, sizeof ar);
另一方面,如果确实要将
unsigned int
s设置为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.
}
(大小i=0;i<10;i++)的
{
ar[i]=UINT\u MAX;//或者您也可以使用“-1”,因为它保证在转换后生成“UINT\u MAX”。
}

在处理原始二进制文件时,我建议使用无符号字符类型,例如
uint8\t
,而不是
char
,因为后者具有实现定义的符号性

在C语言中有两个特殊的规则可以使用:

C116.3.2.3/7

当指向对象的指针转换为指向字符类型的指针时, 结果指向对象的最低寻址字节。连续增量 结果,直到对象的大小,都会产生指向对象剩余字节的指针

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

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

如果指针操作数和结果都指向同一数组对象的元素,或数组对象的最后一个元素之后的元素,,则计算不应产生溢出;否则,行为是未定义的

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

但是,字符类型指针和
int
指针之间的转换会创建未对齐的指针,并且(至少在理论上)会调用未定义的行为,可能还会调用指令陷阱。因此,不能将字符指针强制转换为整数指针并进行比较

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

这意味着以下是一种定义良好(但繁琐且难以读取)的方式来设置数组中的所有字节:

#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;
}
#包括
#包括
内部主(空)
{
无符号整数arr[10];
对于(uint8_t*i=(uint8_t*)arr;(无符号整数*)i!=&arr[10];i+=sizeof(无符号整数))
{
i[0]=0xFF;
i[1]=0xFF;
i[2]=0xFF;
i[3]=0xFF;
}

对于(size_t i=0;i您可能已经尝试并知道了问题的答案。那么您真正想要回答的问题是什么?比如“为什么?”你的意思是让指针指向
ar
还是什么?@Yunnosch仅仅因为某些东西有效并不意味着它是有效的或不会导致UB。@124312344123411234123是正确的,讨论这些概念很重要。但是OP应该问它们的意思,正是因为你指出的。从答案来看,这并不意味着什么你指的“有用的东西”可能是其他东西,OP也没有提到或显示。比如:“尝试过,失败了,为什么?”或者“尝试过类似但功能不同的东西,你知道我的意思,成功了,为什么?”平心而论,
memset
有点生硬。假设您需要将每个int设置为固定的32位值。在一般情况下,最正确的方法可能是使用
for
循环(但这太简单了!)。为什么增量放错了位置?我认为它就像是for循环中控制变量的增量。@Nemora它不是控制变量,它是索引变量。但只有在完成indexing@AnttiHaapala哦,你说得对。我没有太多考虑示例代码。^^那么为什么要投否决票呢?我只是解释OP代码中哪些有效,哪些无效。我从来没有建议你在实际程序中编写这样可怕的代码。奇怪的是,我反驳道;)你总是可以将整数指针强制转换为字符指针,所以最后一部分并不是绝对必要的。@Lundin我使用了字符指针,因为我使用的缓冲区类型就是字符指针想写信给。示例代码:我不知道字符是有符号字符类型,我认为这无关紧要。谢谢你的帮助!:D