Как я хочу отслеживать некоторые переменные, чтобы увидеть, как они меняются, я хочу создать функцию, которая получает строку формата в зависимости от типа переменной и указателя на значение. Я надеюсь, что с помощью строки формата printf будет должным образом определять значение. На самом деле это работает, но с одним исключением - значения поплавка не печатаются должным образом.
Это мой код:
#include <stdio.h>
void pprint (char* fmtstr, void* p)
{
printf(fmtstr,*(long double *)p);
}
int main (int argc, char **argv)
{
char cval = 64;
int ival = -534;
unsigned int iuval = 535;
float fval = 534.64;
double dval = 53432.1;
long double ldval = 534321234.134567;
long long lval = -654321;
unsigned long long luval = 7654321;
pprint ("char: %hhd\n",&cval);
pprint ("int: %d\n",&ival);
pprint ("uint: %u\n",&iuval);
pprint ("float: %f\n",&fval);
pprint ("double: %f\n",&dval);
pprint ("long double: %Lf\n",&ldval);
pprint ("llong: %lld\n",&lval);
pprint ("ullong: %llu\n",&luval);
return 0;
}
и результаты:
char: 64
int: -534
uint: 535
float: 0.000000
double: 53432.100000
long double: 534321234.134567
llong: -654321
ullong: 7654321
Как мы видим, все напечатано хорошо, кроме поплавка. Однако после некоторой модификации функции PPRINT (литье указателя пустоты на поплавок):
printf(fmtstr,*(float*)p);
Результаты:
char: 0
int: 1073741824
uint: 0
float: 534.640015
double: 0.000000
long double: 0.000000
llong: -351285912010752
ullong: 4038940431088615424
Теперь только значение поплавка напечатано правильно. Другим побочным эффектом является, что отливка к любому другому типу приводит к успешному расписанию типов с более низким или одним и тем же размером. (Если я бросил int, он будет печать правильно Chars, но не подходящие). Таким образом, литье в длинные двойные решает эту проблему, так как он самый большой размер.
Однако проблема с поплавками остается. Чтобы распечатать значение поплавка, мне нужно отбрасывать указатель на поплавок, но ничего больше. И наоборот: когда я бросил плавать, все кроме поплавка не удается. Разве не предусмотрено не предусмотрено для чтения данных, расположенных на указанном адресе и передача его на printf? (Такой же указатель, избитый на любой тип, содержит тот же адрес?) Затем строка формата может «прочитать» данные байты в правильном формате - int, int, unsigned int и т. Д.
Я слышал, Это поплавные значения в вариационных функциях преобразуются в удваивание. Это относится к проблеме? Кроме того, в некоторых случаях я не могу обеспечить значение двойным - потому что, например, многие переменные, используемые в OpenGL, плавают (GLFLOAT).
Таким образом, у меня есть 2 вопроса.
Почему поплавки ведут себя отлично от всех других типов.
Может использование этой функции привести к побочным эффектам? Я имею в виду, что при печати, например, INT, Printf получает 12 байт (Sizeof (Double Double)) в качестве второго параметра, но читает только 4 («% d» Строка формата). Из этих 12 байтов первые 4 относятся к значению INT, что я хочу распечатать, а следующие 8 незриваются, которые никогда не читаются printf. Это проблема?
Спасибо.