C 我需要使用'uint8\u t'对'uint8\u t'指针进行算术运算吗?

C 我需要使用'uint8\u t'对'uint8\u t'指针进行算术运算吗?,c,pointers,math,uint8t,uint16,C,Pointers,Math,Uint8t,Uint16,我有一个无符号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;

我有一个无符号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));
}
#包括
#包括
int main(){
uint8_t buff[10]={1,2,3,4,5,6,7,8,9,10};
国际贸易协会;
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\u t
uint8\u 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

 
有人能解释一下下面的代码是否可以接受吗

可以,但是使用
size\u t
而不是
int16\u t
更为正确。这是用于描述事物大小的整数类型,包括数组。而
int16\t
是一种小型的有符号类型


我想使用指针算术而不是数组索引

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


作为旁注,
uint8\u t
的正确
printf
格式说明符是inttypes.h中的
PRIu8
,而不是
%u
。因此,您的代码应更改为:

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


不清楚你想做什么
*buff+1
buff[0]+1
相同,
*buff+ind
buff[0]+ind
相同。这两者都不做指针运算。也许您正在尝试替换buff[ind]?那将是
*(buff+ind)
。但是你会发现结果是一样的。事实上,语言将它们定义为相同的。您将
1
ind
添加到存储到数组
buff
第一个元素的整数中,而不是执行指针算术。我想您的意思是
*(buff+1)
*(buff+ind)
…我想说,
*buff
以及
ind
在第二个
printf
语句中根据类型提升隐式地被转换为
int
,因为它们都非常适合int数据类型大小。因此,它们的总和仍然是
int
类型。但是,
printf
格式说明符需要一个
无符号int
,这里不是这种情况。因此,如果
*buff+ind>=0
,它只输出正确的结果。您的编译器没有发出警告吗?“Godbolt显示了一个小差异”-什么差异?我想他的意思是如果数组可以更大,他就不能在
uint8\u t
上写入大小。这就是为什么问题是关于在
uint8\u t*
中添加一个
uint16\u t
,不幸的是,我在写问题时犯了一个错误。很抱歉我的意思是*(buff+ind)而不是*buff+ind。然而,问题仍然是,
ind
可以是
int16\t
而不是
uint8\t
?C规范只涉及整数类型。负索引没有问题,因为指针可以指向数组中的元素。
大多数类型(尤其是指针)在进行算术运算之前都会转换为无符号整数。
这是错误的。指针不会升级为任何类型,小于
int
的类型将升级为
int
,而不是
无符号int
,除非
sizeof(uint8\u t)==sizeof(int)
。请参见@phuclv,我的意思是
,了解指针算术
,指针当然不会升级。修复了无符号类型的回答
或uint仍然错误的问题said@phuclvRe-fixed
size\u t
用于大小,但索引如何?对于for循环中的计数器,使用
size\t
是好还是坏?@JJAlberto索引几乎总是关于在数组上迭代。那么
size\t
是正确使用的类型,因为您需要与数组大小相同的类型。通常,您不需要担心
size\t
类型太大,除非您手动优化某些8位CPU代码或类似的代码。
printf("%u\n", (unsigned int)buff[1]);