Squeak.ru - шаблоны программирования

Как передать в функцию указатель неизвестного типа?

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

Я уже пробовал использовать универсальный указатель (void *), но он говорит мне, что «void * не является типом указателя на объект». Я не хочу приводить указатель, потому что весь смысл использования указателя в том, что он является универсальным.

void print_string(char *string, void *variable) {
  Serial.print(string);
  Serial.print(": ");
  Serial.print(*variable); # This takes a variable of any type (int, float, double, char *);
  Serial.println();
}

Я хочу иметь возможность предоставить int, double, float или string (char *).

19.06.2019

  • Вы не можете. Однако это C ++, а не C, не так ли? В C ++ вы можете использовать шаблон функции. 19.06.2019
  • Придется кастовать, другого выхода нет. Конечно, весь смысл использования такого указателя заключается в том, что он является универсальным, но он универсален для пользователя - кто-то где-то в конечном итоге должен написать код, который позволяет ему быть универсальным. 19.06.2019
  • @immibis: ничто в этом коде не препятствует тому, чтобы он был C (кроме очевидного разыменования указателя на void, который также не является допустимым C ++). 19.06.2019
  • Это C ++ (Arduino IDE, поэтому C ++ с множеством дополнительных библиотек), но я пытаюсь использовать только C. 19.06.2019
  • @PaulGriffiths Serial.println плюс тот факт, что я уже знаю, что IDE Arduino использует C ++. 19.06.2019
  • Обратите внимание, что void* не является полностью универсальным указателем, поскольку его может быть недостаточно для кодирования указателя функции. 19.06.2019
  • @immibis: Serial.println() может быть совершенно правильным C, но достаточно справедливым, если вы специально распознаете интерфейс. 19.06.2019
  • @PaulGriffiths Как это могло быть правильным C? Что для меня (не зная C ++, но питона) похоже на метод, работающий с объектом? Что это означает в C? Я бы предположил, что это функциональный член структуры с именем Serial, но я не знал, что у вас могут быть функции-члены структуры? 19.06.2019
  • Структуры @AlexStiles в C могут иметь члены, которые являются указателями на функции (например, typedef struct pstring_t { char * chars; int (* length)(); } PString;) 19.06.2019
  • @AlexStiles: Точно так, как сказал @bigwillydos. Serial может быть struct определенным в области файла с парой членов-указателей на функции. 19.06.2019

Ответы:


1

Ответ заключается в том, что вы должны бросить его, хотя и не хотите. Вы пытаетесь разыменовать указатель, который указывает на некоторую ячейку памяти, но вы не даете компилятору никакого сходства с размером этой информации, когда она равна void *, поэтому у него нет способа перевести это в правильную инструкцию сборки для доступ к этой памяти.

19.06.2019
  • Есть ли способ попробовать применить указатель void к различным типам и посмотреть, будет ли он успешным, или он принудительно приведет указатель к этому типу? 19.06.2019
  • @AlexStiles, вы можете преобразовать его в int *, float *, double *, char *, но проблема в том, что если размер того, на что вы его применяете, больше, чем размер того, на что первоначально указывал указатель, вы будете получать доступ к памяти за пределами этого переменная, и это могло быть очень плохо. Я думаю, что решение, которое вы ищете, - это ключевое слово _Generic, которое было введено в стандарте C11. Подробнее об этом читайте здесь: robertgamble.net/2012/01/c11- generic-selections.html 19.06.2019
  • Для полноты важен не только размер, но и представление. Например, int * и float * могут иметь размер 8 байтов и оба могут указывать на объекты размером 4 байта, но вы не сможете что-либо сделать с указанным значением, если только вы знаете, какой из двух основных типов это, потому что, пока вы не знаете, что вы не можете решить, что означают биты. 19.06.2019
  • Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...