我是否需要使用 `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_t
对 uint8_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]);
我有一个无符号 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_t
对 uint8_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]);