Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рекурсивные функции и стек, Передача указателя как аргумента функции 
V
    Опции темы
FiMa1
Дата 2.8.2007, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 408
Регистрация: 23.9.2006

Репутация: 5
Всего: 6



Доброго здравия, друзья!
Есть рекурсивная функция, к примеру такая, как показано ниже. Как известно, при очередном вызове из функции самой себя в стек сохраняются значения параметров функции (в нашем случае 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);
}


Это сообщение отредактировал(а) FiMa1 - 2.8.2007, 14:45
PM   Вверх
bsa
Дата 2.8.2007, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



попробуй вместо int a[] использовать const int *a;
PM   Вверх
Daevaorn
Дата 2.8.2007, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



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

как ты это определил?
Оптимизация.
PM MAIL WWW   Вверх
FiMa1
Дата 2.8.2007, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 408
Регистрация: 23.9.2006

Репутация: 5
Всего: 6



Цитата(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, которое может быть использовано в качестве указателя, но можно и явно ввести указатель) не пересохраняются в стек? Спасибо!

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

Ну, под дебаггером посмотрел все значения агрументов при каждом очередном входе в функцию...
Да, тоже подумалось про оптимизацию..
PM   Вверх
bsa
Дата 2.8.2007, 15:36 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



надо было смотреть не значения, а адреса переменных.
А лучше дизассемблером смотреть.
PM   Вверх
FiMa1
Дата 2.8.2007, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 408
Регистрация: 23.9.2006

Репутация: 5
Всего: 6



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

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

Это сообщение отредактировал(а) FiMa1 - 2.8.2007, 15:45
PM   Вверх
Sartorius
Дата 2.8.2007, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: 8
Всего: 37



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) 


Это сообщение отредактировал(а) Sartorius - 2.8.2007, 15:52
PM MAIL ICQ   Вверх
FiMa1
Дата 2.8.2007, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 408
Регистрация: 23.9.2006

Репутация: 5
Всего: 6



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

Sartorius, ага я уже понял, не успел вот только оправдаться, что такую фигню сморозил... bsa, извини малость. Всем спасибо!
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0636 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.