Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Рекурсивные функции и стек


Автор: FiMa1 2.8.2007, 14:44
Доброго здравия, друзья!
Есть рекурсивная функция, к примеру такая, как показано ниже. Как известно, при очередном вызове из функции самой себя в стек сохраняются значения параметров функции (в нашем случае a, arrsize и n), ну и адреса возврата. Вопрос: каково объяснение тому, что указатели, переданные в функцию в качестве аргументов (в примере имя массива a, которое может быть использовано в качестве указателя, но можно и явно ввести указатель) не пересохраняются в стек? Спасибо!
Код
#include <iostream>
using namespace std;

int sum_of(int a[], int arrsize, int n)
{
    if (n < 1 || n > arrsize)
    {
        cout << "\nError - can only sum 1 to "; 
        cout << arrsize << " elements\n";
        exit(1);
    }
    else if (n == 1)
        return a[0];
    else
        return ( a[n-1] + sum_of(a, arrsize, n-1) );
}

int main()
{
    int arr[] = { 0, 1, 2 };
    const int ARR_ZISE = sizeof(arr) / sizeof(int);

    int sum = sum_of(arr, ARR_ZISE, ARR_ZISE);
}

Автор: bsa 2.8.2007, 15:09
попробуй вместо int a[] использовать const int *a;

Автор: Daevaorn 2.8.2007, 15:14
Цитата(FiMa1 @  2.8.2007,  15:44 Найти цитируемый пост)
Вопрос: каково объяснение тому, что указатели, переданные в функцию в качестве аргументов (в примере имя массива a, которое может быть использовано в качестве указателя, но можно и явно ввести указатель) не пересохраняются в стек? Спасибо!

как ты это определил?
Оптимизация.

Автор: FiMa1 2.8.2007, 15:17
Цитата(bsa @ 2.8.2007,  15:09)
попробуй вместо int a[] использовать const int *a;

Нее, та же картина.. Попробовал ввести еще один аргумент - const int *p - то же самое..
Я, собственно, даже легко допускаю, что такое поведение нормальное, но все же почему.. Все же указатель - то же переменная, получается, если мне понадобиться работать с адресом внутри функции, то я, в каждом новом рекурсивном вызове функции, буду перезаписывать одно и тоже значение...

Добавлено через 1 минуту и 20 секунд
Цитата(Daevaorn @ 2.8.2007,  15:14)
Цитата(FiMa1 @  2.8.2007,  15:44 Найти цитируемый пост)
Вопрос: каково объяснение тому, что указатели, переданные в функцию в качестве аргументов (в примере имя массива a, которое может быть использовано в качестве указателя, но можно и явно ввести указатель) не пересохраняются в стек? Спасибо!

как ты это определил?
Оптимизация.

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

Автор: bsa 2.8.2007, 15:36
надо было смотреть не значения, а адреса переменных.
А лучше дизассемблером смотреть.

Автор: FiMa1 2.8.2007, 15:43
Цитата(bsa @ 2.8.2007,  15:36)
надо было смотреть не значения, а адреса переменных.

Значения переменных-указателей - адреса, они не перезаписывались в стек...
Кстати, для константных указателей вопрос отпадает, я и так их значения поменять в функции не смогу.

Автор: Sartorius 2.8.2007, 15:46
FiMa1, bsa говорит о том, что бы посмотреть адреса этих адресов.  smile С чего значениям то меняться, или ты думаешь что массив по значению в функцию передается ?

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


Неа . все сохраняется вроде
Код

        return ( a[n-1] + sum_of(a, arrsize, n-1) );
0041B1EE  mov         eax,dword ptr [n] 
0041B1F1  sub         eax,1 
0041B1F4  push        eax  
0041B1F5  mov         ecx,dword ptr [arrsize] 
0041B1F8  push        ecx  
0041B1F9  mov         edx,dword ptr [a] 
0041B1FC  push        edx  
0041B1FD  call        sum_of (419B77h) 

Автор: FiMa1 2.8.2007, 15:57
Цитата(Sartorius @ 2.8.2007,  15:46)
FiMa1, bsa говорит о том, что бы посмотреть адреса этих адресов.

Sartorius, ага я уже понял, не успел вот только оправдаться, что такую фигню сморозил... bsa, извини малость. Всем спасибо!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)