Печать типа void в чистом C
У меня есть функция, как
void printMe (void *i)
{
printf("%d", i);
}
где я хочу передать указатель void и распечатать его на экране. Приведенный выше пример хорош, если i-целое число, float или double, но аварийно завершает работу, если i-символ. В C нет перегрузки, как я обычно использую в C++. Итак, вопрос в том, можем ли мы создать функцию в C, которая будет печатать элемент, который является его параметром, и если да, то как это возможно, потому что он полностью ускользает от меня в этот момент.
4 ответов
Вопрос 1: Итак, вопрос в том, можем ли мы создать функцию в C, которая будет печатать элемент, который является параметром
a: не так, как вы хотите. Вам нужно будет передать информацию функции, сообщив ей тип данных, которые вы передаете.
Вопрос 2: и если да, насколько это возможно, потому что это полностью ускользает от меня в этот момент.
A: это ускользает от вас, потому что это невозможно сделать. Нет метаданных, связанных с void* что компилятор или среда выполнения могут использовать, чтобы выяснить, на что они указывают. Вам нужно либо
- передать структуру, содержащую
указатель и информация о том, что
указатель указывает на (например, перечисление.) - передать дополнительный параметр с информация о том, что указатель указывает на
поскольку код стоит единственное, что вы можете напечатать здесь, это адрес, на который я указываю.
указатель void указывает на исходные данные, printf предполагает, что вы знаете, какой тип данных вы печатаете, он не имеет интеллекта и не может "выяснить это" для вас.
Это очень просто.
что вы можете сделать, это передать информацию о типе функции, но затем вы получите что-то очень похожее на printf, где вы передаете строку форматирования, содержащую информацию о типе данных в следующих аргументах.
надеюсь, что это помогает.
также . . . "нет перегрузка в C, как я обычно использую в C++"
даже в c++ перегрузка происходит во время компиляции, и здесь компилятор не может знать, какие данные будут переданы этой функции, поэтому, хотя вы привыкли к перегрузке, она никогда не будет работать так (например, попробуйте то же самое с помощью printf, но скомпилируйте его с помощью компилятора C++, вы получите точно такие же результаты). На самом деле попробуйте
cout << i;
в функции выше, и она передаст вам адрес я указываю не на "ценность" Я. Вам нужно будет бросить i и derference его, прежде чем вы сможете получить его значение
cout << *(int*)i;
Итак, чтобы получить вышеуказанную работу на C++, вам нужно иметь много перегруженных функций (или функцию шаблона, что на самом деле одно и то же, за исключением компилятора, катит функции для вас), например, перегруженные функции
printMe(int i){...}
printMe(double d){...}
printMe(char c){...}
printMe(char* string){...}
в c вам просто нужно дать этим функциям конкретные имена
printInt(int i){...}
printDouble(double d){...}
printChar(char c){...}
printString(char* string){...}
для начала вы печатаете указатель, а не то, на что он указывает. Чтобы распечатать фактическое содержимое, вам нужно передать *i
to printf
, а не i
.
если вы действительно хотите это сделать, одно решение:
void printMe (void *p, int typ) {
switch(typ) {
case TYP_INT: printf("%d", *((int*)p)); break;
case TYP_CHR: printf("%c", *((char*)p)); break;
/* and so on ... */
}
}
Итак, вопрос в том, можем ли мы создать функцию в C, которая будет печатать элемент, который является параметром
Да, мы можем. Такая функция уже является частью стандартной библиотеки - это называется printf
;)
поскольку в C нет перегрузки функции времени компиляции, вы каким-то образом должны указать тип аргументов во время выполнения. The printf
для этого можно использовать строку формата, поэтому нет причин создавать собственную функцию-оболочку когда уже есть рабочее решение.
Если вы пытаетесь напечатать значение указателя, правильное использование printf("%p", i);
. Спецификатор " d "предназначен для целых чисел, а" p " - для указателей. Это ваша ответственность, чтобы получить эти правильные, и плохие вещи могут произойти, если вы их перепутать.
Я не знаю, почему это не удастся для char * , а не int *, и, возможно, у вас есть другие проблемы, вызывающие это. Если он все еще не работает с %p, что-то еще испортилось. Посмотрите, можете ли вы установить какую-то память контролируйте программное обеспечение, чтобы проверить болтающиеся указатели или двойные свободные (), потому что в этот момент умные деньги-это то, что вы где-то повредили память.