сколько раз вызываются следующие функции? - PullRequest
0 голосов
/ 11 сентября 2011

У меня есть следующая программа упражнений из книги. Книга утверждает, что для значений х = 10 и у = 100, функции; min, max, incr и square называются 1, 91, 90 и 90 соответственно. Тем не менее, мне кажется, что их называют следующим числом раз, 1, 1, 1 и 0. Может кто-нибудь объяснить мне номера книг. Спасибо.

#include <stdio.h>

int min(int x, int y){
    return x < y ? x : y;
}

int max(int x, int y){
    return x > y ? y : x;
}

void incr(int *xp, int v) {
    *xp += v;
}

int square (int x){
    return x*x;
}

int main(void){
    int i;
    int x = 10;
    int y = 100;
    int t = 0;

    for (i = min(x, y); i < max(x, y); incr(&i, 1)){
        t += square(i);
        printf("test %i", t);
    }
}

Ответы [ 5 ]

1 голос
/ 11 сентября 2011

Это действительно зависит от компилятора и настроек оптимизации.

Компиляция этой программы (после исправления функции max(), возвращающей максимум) с -O3 показывает, что ни одна из функций на самом деле не вызывается.Компилятор может видеть, что цикл увеличивается с 10 до 100, а переменная увеличивается на 1.

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

Кстати, без исправления max() компилятор мог видеть, что этопустой цикл и выдает функцию main(), которая просто возвращается без установки какой-либо переменной или выполнения каких-либо действий (опять же, с -O3).

0 голосов
/ 11 сентября 2011

Ну, цикл действительно (так как x и y не меняются):

for (i = 10; i < 100; incr(&i, 1))

Первый оператор выполняется только один раз - поэтому min выполняется 1 раз.Условие остановки выполняется один раз в начале, а затем после каждой итерации - так 91 раз.Третье состояние выполняется в конце каждой итерации - так 90 раз.

Итак, книга верна.

0 голосов
/ 11 сентября 2011

В цикле for есть 3 части: инициализация, условие продолжения, приращение.

for(initialization; continue condition; increment) {
    body;
}

Цикл делает это:

  1. Выполнение части инициализации
  2. Проверить условие продолжения (выйти, если истина)
  3. Выполнить код в теле цикла for
  4. Выполнить условие приращения
  5. Вернуться к 2

Таким образом, если мы пройдем через него, min вызывается один раз (инициализация), и до тех пор, пока условие не будет выполнено, max вызывается каждый раз (условие продолжения).Это произойдет от i = 10 до i = y, что составляет 91 раз (один раз в начале и один раз на каждой итерации).

Часть приращения вызывается ровно один раз для каждой итерации, но изначально не вызывается, поэтому он будет вызываться 90 раз (100 - 10).

Функция square будет происходить столько же раз, сколько вызывается приращением (потому что она вызывается перед приращением, но один раз за итерацию).

0 голосов
/ 11 сентября 2011

Вторые два выражения в цикле for оцениваются каждый раз через цикл. Второе выражение выполняется каждый раз, чтобы проверить, должен ли цикл продолжаться, а последнее выражение предназначено для изменения состояния цикла. Например:

for (int x = 0; x < 100; ++x) { /* ... */ }

Выражение x <100 должно оцениваться каждый раз в цикле, чтобы увидеть, изменили ли вы его. <code>++x нужно оценивать каждый раз, потому что это то, что увеличивает x.

Цикл for (expression 1; expression 2; expression 3) - это всего лишь ярлык для общего шаблона:

{
    expression 1;
    if (expression 2)
    {
        do //Do-while + if to demonstrate how `break` and `continue` affect things
        {
            //loop body
            expression 3;
        }
        while(expression 2)
    }
}
0 голосов
/ 11 сентября 2011

Похоже на домашнюю работу, поэтому я не хочу предлагать полное решение, но вот подсказка ... Ключ заключается в понимании, что max вычисляется (вызывается) в конце каждой итерации цикла, потому что результат max можетизменяться после каждой итерации цикла.

Цикл будет продолжаться до тех пор, пока i меньше max (x, y) для данной итерации цикла.

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