2015-03-10 7 views
-1

Простая программа, но я смущен о выходе следующей программы?Вывод программы функции в C

#include<stdio.h> 
int fun(int); 
int main() 
{ 
    float k=3; 
    fun(k=fun(fun(k))); 
    printf("%f\n", k); 
    return 0; 
} 
int fun(int i) 
{ 
    i++; 
    return i; 
} 
+4

Если вы используете отладчик и проходите через программу, вы бы многому научились. – JS1

+0

Каков ваш ожидаемый результат? Каков фактический? –

+0

Является ли выход 5? Что бы вы ожидали? – avim

ответ

1
float k=3; 
fun(k=fun(fun(k))); 
printf("%f\n", k); 

Важно то, что k получает наборы к тому, так что это то, что выводится.

Эта переменная k устанавливается заданием k=fun(fun(k))внутренней, который проходит оригинальный k из 3 к fun(), возвращая 4.

Тогда , что значение 4 снова передается fun(), возвращая 5, что и загружается в k.

Тот факт, что fun() вызывается еще раз, здесь не имеет значения, поскольку результат этого никогда не используется.

0

Если разделить линию

fun(k=fun(fun(k))); 

в несколько строк, было бы:

float temp = fun(k); 
k = fun(temp); 
fun(k); // Return value is ignored. 
+0

Спасибо всем, что у меня есть ... –

1

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

выше программа будет возвращать 5.000000

float k=3; 
fun(k=fun(fun(k))); 

В этой строке ваш переход fun() с k = 3.00000, который будет идти в fun(), где аргумент INT, поэтому десятичные значения не будут рассматриваться, и он будет увеличиваться к на 1 и вернет его. снова у вас есть позвонить fun(), но теперь со значением 4 он будет идти к fun() снова и вернется 5. затем напечатанных K с поплавком %f, так как вы объявили его с поплавком поэтому выход будет 5,000000

+0

Ну, * приблизительно * 5.000000-ish; по-прежнему голосующий ответ - ясность хорошая. – frasnian

+0

@frasnian, я уверен, что одиночные прецизионные поплавки IEEE754 могут обрабатывать добавление одного-трех в два раза и до сих пор поддерживать полную точность, а также очень точно конвертировать между поплавками и ints в интегральном диапазоне 3..5 включительно :-) – paxdiablo

+0

@ paxdiablo: Вы более чем правы, сэр (/ maam): http://en.wikipedia.org/wiki/IEEE_floating_point#Directed_roundings. Для того, что я обычно делаю (финансовые расчеты), я отказался от C/C++ float и дважды долго назад - я просто хочу, чтобы C++ Standard окончательно включал десятичные типы. Прямой стандарт C также - расширения GNU, поддерживающие это, делают меня зуд. – frasnian

0

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

float k=3; 

Во-первых, вы определяете float k и установить его на 3. Это довольно просто. Далее:

fun(k=fun(fun(k))); 

Давайте Разбивка это вторая линия на несколько утверждений:

Во-первых, внутреннее выражение fun(k) оценивается. Это на самом деле довольно сложная операция, так как k является float, поэтому на самом деле первое, что происходит, это k, неявно усеченный и преобразованный в целочисленный тип. К счастью, это дает довольно логическое целочисленное значение 3. Этот аргумент 3 передается значением функции fun(), которая возвращает 4.

Это дает нам значение, которое мы можем использовать, чтобы оценить следующий шаг в нашем сложном маленьком заявлении, которое в настоящее время эффективно выглядит следующим образом:

fun(k=fun(4)); 

Теперь fun() вызывается снова, на этот раз с аргументом из 4 (тип возврата fun() - это целое число, поэтому на этот раз нам не нужно беспокоиться о каком-либо неявном преобразовании типа). fun(4) возвращает 5.

Теперь наше выражение выглядит следующим образом:

fun(k=5); 

В C и C++, назначение выражения (то есть, то, что устанавливает переменную на что-то, например, х = 10;) при оценке возврата значение присвоения. Если бы мы только что написали: (! Снова)

k = 5; 

Неявное преобразование происходит, когда целое значение 5 преобразуется в значение с плавающей точкой (например, 5.00000). Это самое происходит внутри fun(k=5);, но значение выражения назначения, 5.0000, используется здесь как аргумент fun()! Если вы считаете, что это сбивает с толку, это так; вот почему написанный код будет считаться плохим.

Итак, наконец, есть вызов для забавы (5), но поскольку аргумент передается значением, fun() запускает, возвращает 6, но результат не назначен ни на что, поэтому этот конкретный вызов не влияет.

Таким образом, когда вы переходите к печати переменной k, она по-прежнему составляет 5.0000 с момента, когда была оценена операция присваивания от второго до последнего fun(k=5);.

Смежные вопросы