" Мои преобразования верны? Предупреждений компилятора нет, но я просто хочу убедиться. "
Да, все правильно. Нет синтаксических c ошибок и не вызывается неопределенное поведение, потому что все (указательные) типы совпадают в соответствующих выражениях.
u8_8 get(void)
{
static uint8_t ar[8];
return &ar;
}
return &ar;
&ar
имеет тип uint8_t (*)[8]
. Обратите внимание, когда вы используете return ar;
, ar
распадается на указатель на свой первый элемент, введите uint8_t *
; но поскольку к нему применяется оператор &
, этого не происходит. Вместо этого он получает указатель на весь массив uint8_t (*)[8]
.
*(get())
Выражение get()
имеет тип uint8_t (*)[8]
, соответствующий типу возвращаемого &ar
в вызываемой функции get()
.
Разыменование указателя на массив из 8 uint8_t
*(get())
с помощью оператора *
, тип uint8_t (*)[8]
получает массив из 8 элементов uint8_t
, тип uint8_t [8]
. В другой раз массив распадается до указателя на первый его элемент, введите uint_8t *
, который идеально соответствует p
в вызывающем, поэтому присвоение верное.
second(p);
second
ожидает аргумент типа uint8_t *
, который соответствует p
в вызывающей стороне.
Ваш код можно упростить до:
uint8_t* get (void)
{
static uint8_t ar[8];
return ar;
}
void second (uint8_t *data)
{
//...
}
....
int main (void)
{
uint8_t *p = get();
second(p);
}
Примечание: typedef
из typedef uint8_t (*u8_8)[8];
теперь полностью ненужен и избыточен, но вам нужно изменить тип возвращаемого значения get
на uint8_t *
, а также соответствующим образом изменить инициализацию p
в вызывающей программе.
Если вы этого не сделаете Вам не нужен указатель p
в вызывающей стороне, вы даже можете использовать возвращаемое значение get()
непосредственно в качестве аргумента для second()
:
second(get());