在类型转换时是否需要 & 来控制uint8_t指针?[复制]

Is the & needed when type casting to const uint8_t pointer? [duplicate]

提问人:Carl 提问时间:4/22/2023 最后编辑:dbushCarl 更新时间:4/22/2023 访问量:132

问:

我正在使用 Arduino C 中的函数,该函数与将数据写入 SD 卡上的二进制文件相关联。原型函数为:

write(const uint8_t *buf, size_t len);

write 接受指向类型变量的指针,因此如果我正在处理包含类型元素的缓冲区,我必须键入 cast 它们才能使用 write 函数。我用Arduino测试了这一点:const uint8_tuint16_t

uint8_t buffer8[10];
uint16_t buffer16[10];

void setup() {
  Serial.begin(9600);
  for(int i = 0; i<10; i++){
    buffer8[i] = i;
    buffer16[i] = i;
  }
  test(buffer8,sizeof(buffer8));
  Serial.println();
  test((const uint8_t *)buffer16, sizeof(buffer16)); //Without &
  Serial.println();
  test((const uint8_t *)&buffer16, sizeof(buffer16)); //With &
  Serial.println();
}

void loop() {}

void test(const uint8_t *buf, size_t len){
  for(int i = 0; i<len; i++){
    Serial.print(buf[i]);
  }
}

我得到了这个输出,这是正确的:

0123456789
00102030405060708090
00102030405060708090

当我调用我的测试函数时,我做了两次。我第一次不包括 &: .第二次我确实包括 &: .buffer16test((const uint8_t *)buffer16, sizeof(buffer16));test((const uint8_t *)&buffer16, sizeof(buffer16));

但这两个函数调用都会产生相同的输出。所以我的问题是:当我像这样输入强制转换时,我必须包括 & 吗?这在言语中究竟意味着什么?(const uint8_t *)&buffer16

C 指针 类型 投射 Arduino

评论

1赞 John Bollinger 4/22/2023
假设 的作用域内声明将其声明为数组,而不是指针,则无论是否使用,都会获得相同的结果。如果没有 ,则表达式会自动转换为指向其第一个元素的指针(类型),然后通过强制转换将其转换为类型。对于 ,中间指针是指向 类型的整个数组的指针,但从那里到 type 的转换会产生相同的结果。buffer16&&buffer16uint16_t *const uint8_t *&uint16_t (*)[10]const uint8_t *
0赞 Carl 4/22/2023
嘿@JohnBollinger,如果您有意愿,请随时更详细地写下答案,以便给我更多的见解。
1赞 John Bollinger 4/22/2023
我没有把它写成答案,因为它是一个多次的骗局,我目前懒得找到它的目标。
0赞 Carl 4/22/2023
@JohnBollinger 您的第一条评论回答了我的问题。请将其作为答案发布,以便我可以接受它并使此问答帖子“完整”。

答:

3赞 chqrlie 4/22/2023 #1

以下是简单英语的翻译:

  • (const uint8_t *)buffer16表示转换为指向不应用于修改对象的字节的指针。 是一个数组,因此在表达式中使用时,它会衰减为指向其第一个元素的指针。您正在将数组的第一个元素的地址作为指向单个字节的指针传递。buffer16uint8_tbuffer16

  • (const uint8_t *)&buffer16表示转换为指向不应用于修改对象的字节的指针。 是数组的地址,一个指向数组的类型的指针,因此与 的地址相同,因此您还将数组的第一个元素的地址作为指向单个字节的指针传递,但具有无用且令人困惑的中间转换。&buffer16uint8_t&buffer16uint16_t (*)[10]buffer16[0]

请注意,将参数定义为采用 、like 并仅在函数中强制转换参数会不那么令人困惑:testconst void *write()

void test(const void *buf, size_t size) {
    const uint8_t *p = buf;
    for (size_t i = 0; i < size; i++) {
        Serial.print(p[i]);
    }
}

uint8_t buffer8[10];
uint16_t buffer16[10];

void setup() {
    Serial.begin(9600);
    for (int i = 0; i < 10; i++) {
        buffer8[i] = i;
        buffer16[i] = i;
    }
    test(buffer8, sizeof(buffer8));
    Serial.println();
    test(buffer16, sizeof(buffer16));
    Serial.println();
}