Почему моя функция выводит ‘0’?

Вот мой код, я точно не знаю, почему это происходит:

#include <stdio.h>

void foo(float *);

int main()
{
int i = 10, *p = &i;
foo(&i);
}

void foo(float *p)
{
printf("%f\n", *p);
}

ВЫХОД :

0

-3

Решение

Вы вызываете функцию, ожидающую float* с указателем на int. В C ++ это ошибка, и ваш код не компилируется. В C вы, скорее всего, все равно получите предупреждение и неопределенное поведение.

0

Другие решения

Как уже было сказано, вы передаете адрес целочисленной переменной как адрес числа с плавающей запятой одинарной точности.

В идеале такое неявное преобразование должно быть запрещено, но в зависимости от компилятора и того, является ли оно чистым C или C ++, оно может просто привести к предупреждению.

Но почему он печатает ровно 0?

Именно из-за того, как FPN одинарной точности представлены в памяти:

(1 bit of sign)|(8 bits of biased exponent)|(23 bits of significand(mantissa))

10 в двоичном

0|0000 0000|000 0000 0000 0000 0000 0000 1010

Итак, когда интерпретируется как значение с плавающей точкой:

(sign = 0)(biased exponent = 0)(significand = 10)

смещенный показатель — нормальный показатель плюс 127 — http://en.wikipedia.org/wiki/Exponent_bias

Для расчета стоимости будем использовать следующую формулу:

floatValue = ((sign) ? (-1) : (1)) * pow(2, normalExponent) * significand

Это даст:

floatValue = 1 * pow (2, 0 - 127) * 10 = 10 * 2 in pow -127.

Это очень небольшое число, которое при представлении с использованием %f спецификатор превращается в "0" строка.

РЕШЕНИЕ:

Чтобы решить эту проблему, просто используйте временную переменную и явное приведение перед вызовом foo:

int main()
{
int i = 10;

float temp = (float)i;

foo(&temp);
}

void foo(float *p)
{
printf("%f\n", *p);
}

Постскриптум Чтобы избежать подобных проблем в будущем, всегда устанавливайте свой компилятор на максимально реалистичный уровень предупреждений и всегда разбирайтесь с каждым из них перед запуском приложения.

5

Потому что вы объявляете свой целочисленный объект и объект указателя на int а также int * вместо float а также float *,

Вы не можете передать объект типа int * к функции, которая ожидает аргумент типа float * без явного преобразования.

Изменить:

  int i = 10, *p = &i;

в

  float i = 10, *p = &i;

Обратите внимание, что ваш p указатель в main не используется, и его объявление может быть удалено.

1

Вы по существу приводите указатель на int к указателю на число с плавающей точкой. Это допустимо, но BAD — printf пытается понять память, зарезервированную для int, как число с плавающей запятой (которое будет по-разному представлено в памяти), и результаты не определены.

1

Вы пытаетесь прочитать область, выделенную для переменной типа int, и пытаетесь прочитать как float.

Поплавки написаны как мантисса и показатель степени. В зависимости от представления в памяти, вы, вероятно, загружаете экспоненту со своей «10», в то время как мантисса остается нулевой. В результате 0 ^ 10 (или как это интерпретируется) равно 0.

1

Это связано с тем, что вы передаете целое число в функцию, и вы ловите с типом данных с плавающей точкой.

Когда вы его скомпилируете, вы получите предупреждение, если включите флаги предупреждения.

root@sathish1:~/My Docs/Programs# cc float1.c
float1.c: In function ‘main’:
float1.c:11:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
float1.c:3:6: note: expected ‘float *’ but argument is of type ‘int *’

Это ясно говорит вам, что вы делаете.

Ваша функция исключает float *, но вы проходите int *, Таким образом, при печати он будет искать соответствующую область памяти и попытаться распечатать ее. Но переменные типа float хранятся в стандарте IEEE 754, но функция получает адрес целого числа, поэтому она попытается распечатать данные в этой ячейке памяти (int не хранится в стандарте IEEE 754). Таким образом, результат не определен.

1
По вопросам рекламы [email protected]