我是否需要使用 `uint8_t` 对 `uint8_t` 指针进行算术运算?

Do I need to use `uint8_t` to do arithmetics on a `uint8_t` pointer?

我有一个无符号 8 位整数数组,但是这个数组的长度可以大于 255。我想使用指针算法而不是数组索引。 如果以下代码是否可以接受,有人可以解释我吗?我怀疑 ind 变量相对于 buff 具有不同的类型,这可能被视为糟糕的编程。

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

int main(){
    uint8_t buff[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int16_t ind;
    
    ind = 1;
    
    printf("%u\n", *(buff + 1));
    printf("%u\n", *(buff + ind));
}

Godbolt 在 *(buff + 1)*(buff + ind) 之间显示出细微差别,但它似乎有效。

数组索引已经是指针算法,因为 buff[i] 定义为 *(buff+i)。但是前者更容易阅读(和理解)。

我也不明白作为数组索引的最大值的整个 255 限制与数组的类型无关,只与它的大小有关。

数组索引始终是 size_t 类型,它是一种无符号整数类型,能够容纳任何可能的数组索引。如果您使用任何其他整数类型作为索引,编译器会自动将该值转换为 size_t.

所以不,你不需要使用 uint8_tuint8_t* 进行算术运算。

大多数类型在进行算术运算之前都会转换为 int(尤其是指针算术),因此无论您对 ind 使用 uint8、uint16 还是 uint32 都没有什么影响。

你正在做的是向指针添加一些东西,这是一个地址(在 32 位或 64 位上),这意味着它指向的类型(uint8_t 在你的情况下)对指针的类型。

但是,请记住,指针算法中指向的对象的大小很重要,因为它不会逐字节移动,而是逐对象移动。

uint8_t *char_ptr = 0x1000;
uint32_t *int_ptr = 0x1000;

char_ptr += 1;
int_ptr += 1;

printf("0x%x", char_ptr); // 0x1001
printf("0x%x", int_ptr);  // 0x1004

 

Can someone explain me if the following code is acceptable or not?

没关系,但使用 size_t 而不是 int16_t 会更正确。这是用于描述事物大小的整数类型,包括数组。而 int16_t 是一个小的有符号类型。


I want to use pointer arithmetics instead of array indexing

为什么?这样做的唯一结果就是降低代码的可读性。数组索引与指针运算一样,只是“语法糖”。请学习.


作为旁注,uint8_t 的正确 printf 格式说明符是 inttypes.h 中的 PRIu8,而不是 %u。所以你的代码应该改为:

printf("%" PRIu8 "\n", buff[1]);

printf("%u\n", (unsigned int)buff[1]);