MyTetra Share
Делитесь знаниями!
Вызов функции по известному адресу в языке Си - абстрактный тип данных указателя на функцию
Время создания: 18.02.2022 10:21
Автор: xintrea
Текстовые метки: язык, Си, функция, указатель, адрес, тип данных
Раздел: Компьютер - Программирование - Язык C (Си)
Запись: xintrea/mytetra_syncro/master/base/16451688711iqlk86uwy/text.html на raw.github.com

Если известен адрес начала функции в оперативной памяти в виде числа (часто эти числа известны для микроконтроллеров), то такую функцию можно вызвать в языке Си. Делается это следующим кодом:



// Константа 0xA000 – шестнадцатеричный адрес

// функции, которую вызывает main

// void(*)(void) – это абстрактный тип данных,

// описывающий указатель на функцию

void (*pf)(void) = (void(*)(void))0xA000;


void main()

{

// Вызов функции по укзателю на функцию

(*pf)();

}



Если попытаться понять тип выражения (void(*)(void))0x1000 стандартным подходом "вывод типа по спирали", то сразу возникнет вопрос: а где в этом выражении неизвестное имя переменной, от которого надо начинать выводить тип? Здесь используется очередная особенность синтаксиса языка, в которой совмещается синтаксис написания указателя на функцию и абстрактный тип данных. Использование абстрактного типа данных в данной записи необходимо из-за того, что в вышеуказанном выражении происходит приведение числового значения 0xA000 к абстрактному типу (void(*)(void)), а этот тип, по своей сути, представляет собой указатель на функцию.


В абстрактном типе данных не используется какое-либо имя переменной. Точно так же, в абстрактном типе данных при описании указателя на функцию, не используется имя функции. В такой ситуации надо пользоваться следующим мнемотическим правилом:



Видишь где-то в середине конструкцию "(*)" ? Значит это абстрактное описание указателя на функцию, если после данной конструкции имеется описание типов параметров в круглых скобках, а перед ней тип возвращаемого значения.


В вышеприведенном примере параметры функции описаны как (void), т .е. функция не имеет параметров. А тип возвращаемого значения описан как void, т. е. функция ничего не возвращает.



Имя переменной-указателя на функцию, при определении переменной, вписывается после звездочки конструкции "(*)" абстрактного типа. Чтобы это понять, надо сравнить левую и правую часть присваивания в инициализации указателя на функцию:



void (*pf)(void) = (void(*)(void))0xA000;



Здесь видно, что имя указателя на функцию pf, практически, было вписано в "(*)", после звездочки.


Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования