Необходимо сделать, чтобы переменная, используемая в рекурсивной функции (при каждом первом вызове последней принимала одно и то же значение)
Модератор: Модераторы разделов
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Я вижу 2 пути:
1) Объявляем переменную (допустим "c") внешней, инициализируем её нужным значением. Затем делаем вызов рекурсивной функции a (), в которой и используем эту переменную с нужным уcтановленным значением. Этот способ мне неудобен, ибо если придётся скопировать куда-нибудь текст функции a (), в это же место придётся скопировать и объявление внешней переменной "c". Нельзя ли обойтись без "перетаскивания" переменной "c" за функцией "a"?
2)Объявляем функцию a () как принимающую аргумент: a (int c). Первый вызов будет выглядеть так: a (<необходимое значение>) Этот способ был бы удобен, если бы не одно "но": я предполагаю, что разрабатываемая мной функция a () при первом вызове будет использовать всегда одно и то же значение "с". И это значение равно 0. Не один, не два, а именно 0 И мне при каждом первом вызове a () (она может вызываться в разных программах). Необходимо будет вручную писать одно и то же значение аргумента 0. Вот так: a (0)
Как обойтись без такого прописывания? Или третьего способа не дано? Заранее спасибо.
P. S. Объявить в функции а () переменную "c" и инициализировать её нужным мне значением я тоже не могу, ибо предполагается, что при каждом новом рекурсивном вызове функции a () переменная "c" должна быть разной (должна увеличиваться на 1)
1) Объявляем переменную (допустим "c") внешней, инициализируем её нужным значением. Затем делаем вызов рекурсивной функции a (), в которой и используем эту переменную с нужным уcтановленным значением. Этот способ мне неудобен, ибо если придётся скопировать куда-нибудь текст функции a (), в это же место придётся скопировать и объявление внешней переменной "c". Нельзя ли обойтись без "перетаскивания" переменной "c" за функцией "a"?
2)Объявляем функцию a () как принимающую аргумент: a (int c). Первый вызов будет выглядеть так: a (<необходимое значение>) Этот способ был бы удобен, если бы не одно "но": я предполагаю, что разрабатываемая мной функция a () при первом вызове будет использовать всегда одно и то же значение "с". И это значение равно 0. Не один, не два, а именно 0 И мне при каждом первом вызове a () (она может вызываться в разных программах). Необходимо будет вручную писать одно и то же значение аргумента 0. Вот так: a (0)
Как обойтись без такого прописывания? Или третьего способа не дано? Заранее спасибо.
P. S. Объявить в функции а () переменную "c" и инициализировать её нужным мне значением я тоже не могу, ибо предполагается, что при каждом новом рекурсивном вызове функции a () переменная "c" должна быть разной (должна увеличиваться на 1)
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 88
- ОС: Gentoo Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
А чем не вариант указать 0 умолчальным аргументом при объявлении рекурсивной ф-ции?
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Вариант! Чувствую, что вариант! Вот нечто подобное я и мыслил! Только... как указывать-то? Я прямо в растерянности- даже упоминания об этом не мелькало нигде в книгах. Вот, к примеру, K&R. Судя по полезности Вашего предложения я давно должен был о нём прочесть. Не могу найти.
Язык C
Язык C
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 1073
- Статус: столлманист
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Вот это Вы хотели?
Код: Выделить всё
#include <stdio.h>
void foo()
{
static int c = 0;
c++;
printf("%d\n", c);
if(c < 10)
foo();
}
int main()
{
foo();
return 0;
}
"И может собственных Платонов и быстрых разумом Невтонов российская земля рождать."
М. В. Ломоносов
М. В. Ломоносов
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Да! Но как это может быть? (При задавании вопроса я, естественно, имел ключевое слово "static" ввиду. Но мне и в голову не приходило с ним эксперементировать) ибо : (цитата из K&R)
"Объявление static применимо и к внутренним переменным. Внутренние статические переменные являются локальными по отношению к конкретной функции, как и автоматические. Но, в отличиеот автоматических статические переменные продолжают существовать непрерывно, а не создаются и уничтожаются при вызове и завершении функции. Получается, что внутренние статические переменные являются средством постоянного хранения скрытой информации внутри одной функции"
Я не прочёл здесь, что объявление статической функции действительно один раз, а остальные объявления игнорируются компилятором... Или это ускользнуло от моего внимания?:
"Это является ключевой концецией статических переменных- они не создаются и не исчезают при вызове и окончании работы функции. Значения таких переменных остаются такими, какими они были при последнеи вызове функции, и не изменяются до следующего вызова" (Стефан Кочан)
Меж тем примеров с рекурсией в книге нет. Иначе и вопроса бы не возникло. Ну, не написано нигде, что эти правила распространяются и на рекурсивные вызовы. Странно, конечно. Надо будет найти, где это прописано явно, а не косвенно.
Большое спасибо.
"Объявление static применимо и к внутренним переменным. Внутренние статические переменные являются локальными по отношению к конкретной функции, как и автоматические. Но, в отличиеот автоматических статические переменные продолжают существовать непрерывно, а не создаются и уничтожаются при вызове и завершении функции. Получается, что внутренние статические переменные являются средством постоянного хранения скрытой информации внутри одной функции"
Я не прочёл здесь, что объявление статической функции действительно один раз, а остальные объявления игнорируются компилятором... Или это ускользнуло от моего внимания?:
"Это является ключевой концецией статических переменных- они не создаются и не исчезают при вызове и окончании работы функции. Значения таких переменных остаются такими, какими они были при последнеи вызове функции, и не изменяются до следующего вызова" (Стефан Кочан)
Меж тем примеров с рекурсией в книге нет. Иначе и вопроса бы не возникло. Ну, не написано нигде, что эти правила распространяются и на рекурсивные вызовы. Странно, конечно. Надо будет найти, где это прописано явно, а не косвенно.
Большое спасибо.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Бывший модератор
- Сообщения: 2521
- Статус: статус, статус, статус
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
ВЕЗДЕ написано явно:
Но, в отличиеот автоматических статические переменные продолжают существовать непрерывно, а не создаются и уничтожаются при вызове и завершении функции.
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Да! Я понял, что мне мешало применить "static" и что держит меня в недоумении! То, что значения этих переменных постоянны, это да. Но они постоянны всегда! Переменная "c", инициализированная значением 0, должна всегда оставаться 0! Ибо вот:
"Значения таких переменных остаются такими, какими они были при последнем вызове функции, и не изменяются до следующего вызова" (Стефан Кочан)
Имеем вызов функции foo, в нём объявлена стачиеская переменная "c равная 0. И она должна остаться такой какой была до следующего вызова! Почему она вдруг инкременируется? Cтановится вдруг равной 1? Написано же: "Значения таких переменных остаются такими, какими они были при последнем вызове функции, и не изменяются до следующего вызова" (Стефан Кочан) Я уже повторяюсь, извините.
Ну, понятно, что если переменная объявлена со static то всякое обращение к такой переменной есть обращение к одной и той же области памяти. Так? Так. Но я прочёл, помимо этого, что в этой области памяти должно быть представлено одно и только одно значение!
"Значения таких переменных остаются такими, какими они были при последнем вызове функции, и не изменяются до следующего вызова" (Стефан Кочан)
Имеем вызов функции foo, в нём объявлена стачиеская переменная "c равная 0. И она должна остаться такой какой была до следующего вызова! Почему она вдруг инкременируется? Cтановится вдруг равной 1? Написано же: "Значения таких переменных остаются такими, какими они были при последнем вызове функции, и не изменяются до следующего вызова" (Стефан Кочан) Я уже повторяюсь, извините.
Ну, понятно, что если переменная объявлена со static то всякое обращение к такой переменной есть обращение к одной и той же области памяти. Так? Так. Но я прочёл, помимо этого, что в этой области памяти должно быть представлено одно и только одно значение!
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 73
- ОС: KUbuntu 8.04 Hardy Heron
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
promov, цитата в вашем последнем посте, очевидно, взята из описания какого-то конкретного примера, где это действительно так. В общем случае это неверно.
Статические переменные - это, как ни странно, все же переменные, а не константы.
Статические переменные - это, как ни странно, все же переменные, а не константы.
-
- Сообщения: 1537
- Статус: Оказывается и без KDE есть жизнь
- ОС: FreeBSD 8.0-RC2
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Думаю, что можно обойтись и без использования static.
Для этого необходимо определить функцию как
Тогда при первом ее вызове аргумент можно не указывать, а внутри этой функции вызывать её же с нужным аргументом.
Для этого необходимо определить функцию как
Код: Выделить всё
void foo(int c=0);
Тогда при первом ее вызове аргумент можно не указывать, а внутри этой функции вызывать её же с нужным аргументом.
Rock'n'roll мертв © БГ
-
- Сообщения: 323
- ОС: Debian Lenny
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
promov писал(а): ↑28.02.2008 21:30Да! Я понял, что мне мешало применить "static" и что держит меня в недоумении! То, что значения этих переменных постоянны, это да. Но они постоянны всегда! Переменная "c", инициализированная значением 0, должна всегда оставаться 0! Ибо вот:
"Значения таких переменных остаются такими, какими они были при последнем вызове функции, и не изменяются до следующего вызова" (Стефан Кочан)
Имеем вызов функции foo, в нём объявлена стачиеская переменная "c равная 0. И она должна остаться такой какой была до следующего вызова! Почему она вдруг инкременируется? Cтановится вдруг равной 1? Написано же: "Значения таких переменных остаются такими, какими они были при последнем вызове функции, и не изменяются до следующего вызова" (Стефан Кочан) Я уже повторяюсь, извините.
Ну, понятно, что если переменная объявлена со static то всякое обращение к такой переменной есть обращение к одной и той же области памяти. Так? Так. Но я прочёл, помимо этого, что в этой области памяти должно быть представлено одно и только одно значение!
блин. вы сами своим словам противоречите.
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Нет. Имеем рекурсивную функцию a ()
void a () {
static int c= 0;
c++;
a ();
}
Самый первый вызов функции даёт нам с=0, потом с станвится равной единице. Хотя она не имеет права такой становиться! Она, пока функция а снова не вызовется не должна изменяться! "не изменяются до следующего вызова" (Стефан Кочан)
Вы поймите меня правильно, я принял на веру то, что мне предложили и так сейчас делаю. И делал бы дальше. Но раз уж Вы снова к этому вопросу возвращаетесь- давайте уж добьём его тогда, что ли.
Ну да, переменная "с" не константа. Но дело-то ведь не в том, как её назвать, дело в том, как она будет себя вести, согласно этому называнию. По мне (и по цитатам тоже) получается, что именно как константа и должна себя вести
void a () {
static int c= 0;
c++;
a ();
}
Самый первый вызов функции даёт нам с=0, потом с станвится равной единице. Хотя она не имеет права такой становиться! Она, пока функция а снова не вызовется не должна изменяться! "не изменяются до следующего вызова" (Стефан Кочан)
Вы поймите меня правильно, я принял на веру то, что мне предложили и так сейчас делаю. И делал бы дальше. Но раз уж Вы снова к этому вопросу возвращаетесь- давайте уж добьём его тогда, что ли.
Ну да, переменная "с" не константа. Но дело-то ведь не в том, как её назвать, дело в том, как она будет себя вести, согласно этому называнию. По мне (и по цитатам тоже) получается, что именно как константа и должна себя вести
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 3339
- ОС: Slackware 12.2, ArchLinux 64
-
- Сообщения: 323
- ОС: Debian Lenny
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
promov писал(а): ↑01.03.2008 17:42Нет. Имеем рекурсивную функцию a ()
void a () {
static int c= 0;
c++;
a ();
}
Самый первый вызов функции даёт нам с=0, потом с станвится равной единице. Хотя она не имеет права такой становиться! Она, пока функция а снова не вызовется не должна изменяться! "не изменяются до следующего вызова" (Стефан Кочан)
Вы поймите меня правильно, я принял на веру то, что мне предложили и так сейчас делаю. И делал бы дальше. Но раз уж Вы снова к этому вопросу возвращаетесь- давайте уж добьём его тогда, что ли.
Ну да, переменная "с" не константа. Но дело-то ведь не в том, как её назвать, дело в том, как она будет себя вести, согласно этому называнию. По мне (и по цитатам тоже) получается, что именно как константа и должна себя вести
где в вашей цитате говорится что эта переменная константа??? там говорится что по завершению функции память, выделенная как статическая (static), cохраняется, а не затирается и это не значит что её ничего нельзя присваивать во время выполнения функции. не будем больше спорить.
-
- Сообщения: 73
- ОС: KUbuntu 8.04 Hardy Heron
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
promov, когда сомневаетесь в ответе на подобные вопросы, попробуйте себе ответить на другой простой вопрос: чем отличается константный указатель от указателя на константу? Ответ придет сам собой.
А утверждение Стефана Кочана, еще раз повторяю, следует читать в контексте, а не само по себе. И не надо верить в то, что написано в книжке, как в абсолютную истину
А утверждение Стефана Кочана, еще раз повторяю, следует читать в контексте, а не само по себе. И не надо верить в то, что написано в книжке, как в абсолютную истину
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
А сейчас нужно доразбираться с этим и закрыть тему.
Ваше предложение не работает. Имеем исполняемый файл <имя файла>
Команда сс <имя файла> Вывод
Синтаксис не тот, как видим. Нельзя в определении функции писать void a (int c= 0), а нужно всё-таки писать void a (int c)
Честно говоря, я рад- но не тому, что Вы оказались неправы (это побочное явление) а тому, что хоть одной неоговорённой допустимостью в языке C стало меньше.
Shura писал(а): ↑01.03.2008 16:05Думаю, что можно обойтись и без использования static.
Для этого необходимо определить функцию как
Код: Выделить всё
void foo(int c=0);
Тогда при первом ее вызове аргумент можно не указывать, а внутри этой функции вызывать её же с нужным аргументом.
Ваше предложение не работает. Имеем исполняемый файл <имя файла>
Код: Выделить всё
#include <stdio.h>
void a (int c= 0) {
printf ("c= %d\n", c);
c++;
if (c< 5){
a ();
}
}
int main () {
void a (int c);
a ();
return 0;
}
Команда сс <имя файла> Вывод
Код: Выделить всё
po.c:3: error: expected ';', ',' or ')' before '=' token
po.c: In function 'main':
po.c:13: error: too few arguments to function 'a'
Синтаксис не тот, как видим. Нельзя в определении функции писать void a (int c= 0), а нужно всё-таки писать void a (int c)
Честно говоря, я рад- но не тому, что Вы оказались неправы (это побочное явление) а тому, что хоть одной неоговорённой допустимостью в языке C стало меньше.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 636
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
promov писал(а): ↑02.03.2008 16:22А сейчас нужно доразбираться с этим и закрыть тему.
Ваше предложение не работает. Имеем исполняемый файл <имя файла>
Код: Выделить всё
#include <stdio.h> void a (int c= 0) { printf ("c= %d\n", c); c++; if (c< 5){ a (); } } int main () { void a (int c); a (); return 0; }
Команда сс <имя файла> Вывод
Код: Выделить всё
po.c:3: error: expected ';', ',' or ')' before '=' token po.c: In function 'main': po.c:13: error: too few arguments to function 'a'
Синтаксис не тот, как видим. Нельзя в определении функции писать void a (int c= 0), а нужно всё-таки писать void a (int c)
Честно говоря, я рад- но не тому, что Вы оказались неправы (это побочное явление) а тому, что хоть одной неоговорённой допустимостью в языке C стало меньше.
Так можно писать в С++, но не в С.
-
- Сообщения: 323
- ОС: Debian Lenny
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
может так?
Код: Выделить всё
void foo ( c )
int c = 0;
{
}
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Не надо гадать. Нужно попробовать у себя на компьютере и в случае удачи предложить.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 323
- ОС: Debian Lenny
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Необходимо сделать, чтобы переменная, используемая в рекурсивной функции
Не помогает. Да и не должно помочь- всё равно выдаётся ошибка в синтаксисе при определении аргументов функции. Впрочем, уже выяснено, что предложенный мне вариант для C++, а я на С пишу.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?