Скажите, что функция принимает указатель на пустоту как аргумент: int func(void *p);
Как определить или угадать тип того, на что указывает p?C: Экстраполирующий тип из указателя void
ответ
В общем, вы не можете. В некоторых случаях, если есть гарантия на то, на что указывает p, вы можете посмотреть содержимое на этом и после этого адреса, чтобы узнать. Как правило, ваша функция должна знать, что она передается, если только она не передает ее.
Аргументы данных и функций в C - это всего лишь куча бит, сосредоточенных вместе. Если вы не используете некоторые из этих битов, чтобы рассказать вам, что такое биты, нет единого способа идентифицировать его.
Короткий ответ - вы не можете.
В C нет времени выполнения информации , если вы не предоставите это, но посмотрите на printf(3)
семьи и посмотреть, насколько легко стрелять себе в ногу с несовпадением формата спецификации и фактического типа аргумента.
Тип системы - ваш друг. Используй это.
Уверен, что вы можете, и это тоже легко. Это C, делайте все, что хотите, как хотите.
Внесите тип системы. Поместите все, что вы переходите в структуру, сделайте первый байт или два магического числа, чтобы определить, что содержит эта структура вне магического числа.
Сделать некоторые функции для создания/получения/установки/уничтожения «типизированных переменных».
Внесите некоторые другие функции для добавления и регистрации новых типов во время выполнения.
Создайте несколько определений, чтобы упростить чтение и тип конструкций.
Прежде чем вы это узнаете, у вас будет хорошая система типов, которую вы можете использовать для своих проектов, и она всегда будет ТОЧНО, что вы хотите и нуждаетесь, потому что ВЫ ее сделали.
Вы можете сходить с ума и превратить его в полноценную объектно-ориентированную систему. Или сохраните себе работу и используйте работу всех других людей, которые уже сошли с ума. http://en.wikipedia.org/wiki/GObject
Итак, как это работает, когда функция, которую вы пишете, вызывается из кода, который вы не контролируете? – WhirlWind
Если функция вызывается из кода, который вы не контролируете, вы создаете API/библиотеку, поэтому вам нужно документировать интерфейс и функции для создания/получения/установки/уничтожения типизированных переменных. Если по какой-либо причине контролер является контролирующим, и они не хотят/отказываются использовать вашу пользовательскую «типизированную» систему, тогда вам не повезло. Вы должны позволить им решить, как они собираются передать вам введенную информацию и код. – Antebellum
У меня возникла аналогичная проблема, и мне пришлось написать набор инструкций для проекта языка программирования. Я столкнулся с этой проблемой, потому что у меня был массив указателей на функции, чтобы функции можно было перечислить и запустить в цикле for (для таких вещей, как интерактивная справка и синтаксис и т. Д.). Например:
struct List_Str *(*InstructionSet[])(struct List_Str *ContextPrefix,struct List_Str *ContextSuffix)=
{
AAVF,Add,AddEmotions,AddEmoDebug,AddScope,...
};
Теперь вы можете легко сделать то же самое с гольца * вместо STRUCT List_Str * типов, а затем преобразовать все данные в формат строки, используя snprintf и atoi и atof и другие функции преобразования. Если вы делаете:
man isalpha
Это показывает вам множество функций в ctype.h, которые могли бы дать вам идеи, как определить, какой тип данных проводится в строках.
Складывание всех типов в «волокнистый» формат обеспечивает невероятную гибкость и регулярность, но автоматическое преобразование данных из строк в целые числа, поплавки и т. Д. Является трудоемким, но плодотворным, как только процедуры либризируются.
Если вы намерены хранить двоичные данные, вы не можете использовать строки, так как в двоичных данных может быть 0 символов, и это смущает функции strlen. Кроме того, вы не имеете представления о том, что было malloc'd, когда оно покидает область действия, поэтому сохраняя длину разыменованных данных до того, как данные будут рекомендованы в первых байтах char *.
Последнее, что я бы не рекомендовал хранить данные в void *, это слишком расплывчато. Я рекомендую использовать char *, поскольку он немного более конкретный, может содержать все, что void * может, и компилятор сообщит вам заранее, если что-то выглядит подозрительно.
Если вы используете 'char *' в качестве общего указателя данных, слишком легко ИМХО случайно разыменовать указатель без предварительного преобразования в соответствующий тип. –
- 1. Несовместимый тип указателя - отправка void в тип параметра void NSArray
- 2. Выделение указателя void в C++
- 3. Значения указателя Void, сравнивающие C++
- 4. копировать значение указателя void C
- 5. Есть ли способ переносить тип указателя void *?
- 6. c печать строки указателя void
- 7. Недостатки указателя void в C++
- 8. C void * аргумент указателя функции
- 9. Вывод функции указателя void
- 10. Перейти эквивалент указателя void в C
- 11. несовместимый тип указателя - C
- 12. Синтаксис C++ для указателя const void
- 13. Передача строки из C++ в C# с использованием указателя void
- 14. Печать значений указателя void
- 15. несовместимый тип указателя в C
- 16. Узнайте, какой тип C++ Void Pointer
- 17. C тип указателя отливать
- 18. Ctypes - Передача указателя Void из Python
- 19. Тип данных VOID в C
- 20. Назначение указателя на тип CLR для void * использование небезопасных?
- 21. Неполный тип 'void' не присваивается c
- 22. Доступ к члену указателя void объекта C++
- 23. проверить размер указателя void в макросе c
- 24. Назначение из указателя void на другой указатель void
- 25. Как скопировать данные из указателя void в C++?
- 26. Почему typex из указателя void необходим в C++?
- 27. массив указателя void
- 28. Расчет указателя void в gcc
- 29. Кастинг указателя void на указатель произвольного типа
- 30. Проблемы с получением int из указателя void
Голосование ... вы знаете, потому что вы убедились в том, что в остальной части вашей программы. Если это звучит хрупко, это потому, что оно хрупкое. Добро пожаловать в C. Используйте менее хрупкую систему, в которой вы можете. –
Я помню некоторый код Мотива (всего прочего), где бы вы не указали указатель, и вы бы посмотрели на первые байты после указателя, чтобы определить, что это за тип, и затем вы соответствуете этому типу. Какой беспорядок. – WhirlWind
Я не буду делать это на практике. Мне было просто любопытно, как это можно сделать. Кроме того, расширение GNU C предоставляет оператор typeof(), который (я думаю) сможет определить тип разыменованных (т. Е. Typeof (* p)), но я еще не использовал его. – Yktula