表达式中使用的数组指示符(极少数例外)被转换为指向其第一个元素的指针。
来自 C 标准(6.3.2.1 左值、数组和函数指示符)
3 除非它是 sizeof 运算符的操作数或一元 &
运算符,或者是用于初始化数组的字符串文字,
具有“类型数组”类型的表达式被转换为
类型为“pointer to type”的表达式,指向初始
数组对象的元素并且不是左值。如果数组对象
有注册存储类,行为未定义。
因此在此声明中
uint8_t* pNextInputBytes = pInputByte;
用作初始化器的数组被转换为指向其第一个元素的指针,并且类型为int *。这个值被分配给声明的指针。
在此声明中
pNextInputBytes = &pInputByte;
对数组类型的对象应用一元运算符 &。所以表达式&pInputByte 的类型是uinmt8_t ( * )[byteCount]。但是在赋值的左侧有一个uint8_t * 类型的对象。没有从一种类型到另一种类型的隐式转换。所以编译器会报错。
你可以写
uint8_t pInputByte[byteCount];
uint8_t (*pNextInputBytes )[byteCount];
pNextInputBytes = &pInputByte;
为了更清楚,为数组类型引入一个 typedef 名称
typedef uint8_t T[byteCount];
然后你可以通过以下方式声明数组和指向数组的指针
T pInputByte;
T *pNextInputBytes = &pInputByte;
现在如果将指针声明中的 typedef 名称 T 替换为定义的类型,那么您将得到
uint8_t ( *pNextInputBytes )[byteCount] = &pInputByte;
要查看其中一个类型为uint8_t * 和另一个类型为uint8_t ( * )[byteCount] 的两个指针之间的区别,请编写以下演示程序。
#include <stdio.h>
#include <stdint.h>
int main(void)
{
size_t byteCount = 10;
uint8_t pInputByte[byteCount];
uint8_t *pNextInputBytes1 = pInputByte;
uint8_t ( *pNextInputBytes2 )[byteCount] = &pInputByte;
printf( "sizeof( *pNextInputBytes1 ) = %zu\n", sizeof( *pNextInputBytes1 ) );
printf( "sizeof( *pNextInputBytes2 ) = %zu\n", sizeof( *pNextInputBytes2 ) );
return 0;
}
程序输出是
sizeof( *pNextInputBytes1 ) = 1
sizeof( *pNextInputBytes2 ) = 10
注意,数组名称中使用的前缀p会混淆代码读者。