Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.04.2012, 21:51   #1
Blondy
Участник клуба
 
Аватар для Blondy
 
Регистрация: 07.07.2009
Сообщений: 1,385
По умолчанию С++ Visual как правильно вызвать функцию с указателем?

Здраствуйте!
Разбираюсь с бинарными деревьями - нашла пример функции создания дерева. Там при объявлении и описании функции используется указатель на указатель типа структура. По логике вещей при вызове функции мы передаем только указатель и количество элементов дерева. Но компилятор пишет:
Цитата:
1> error C2275: 'BinaryTree' : illegal use of this type as an expression
А как сделать вызов функций создания и печати на экран правильно? У меня с указателями на указатели очень плохо((((

Код:
#include <iostream>
#include <conio.h>
#include <time.h>

using namespace std;

struct BinaryTree{
       int Data; //поле данных
       BinaryTree* Left; //указатель на левого потомка
       BinaryTree* Right;//указатель на правого потомка
};

BinaryTree* BTree = NULL;

void Make_Binary_Tree(BinaryTree** Node, int n);
void Print_BinaryTree(BinaryTree* Node, int l);



int main () {

int n = 0;
cout<<"Введите количество элементов"<<endl;
cin>>n;

Make_Binary_Tree(BinaryTree* BTree, n);//вызов функции создания дерева

Print_BinaryTree(BinaryTree BTree,  l)//печать на экран дерева

	getch();
	return 0;
}

///////Функции ////////////////////////////
void Make_Binary_Tree(BinaryTree** Node, int n) //создание дерева
{
  BinaryTree** ptr;//вспомогательный указатель
  srand(time(NULL)*1000);
  while (n > 0) {
    ptr = Node;
    while (*ptr != NULL) {
      if ((double) rand()/RAND_MAX < 0.5) 
        ptr = &((*ptr)->Left);
      else ptr = &((*ptr)->Right);
    }
    (*ptr) = new BinaryTree();
    cout << "Введите значение ";
    cin >> (*ptr)->Data;
    n--;
  }
}

//печать бинарного дерева
void Print_BinaryTree(BinaryTree* Node, int l){
  int i;
  if (Node != NULL) {
    Print_BinaryTree(Node->Right, l+1);
    for (i=0; i< l; i++) cout << "    ";
    printf ("%4ld", Node->Data);
    Print_BinaryTree(Node->Left, l+1);
  }
  else cout << endl;
}
"Все мы жаждем чудес. Чисто человеческое свойство." Carl Sagan
Blondy вне форума Ответить с цитированием
Старый 03.04.2012, 00:36   #2
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Blondy

Разбираюсь с бинарными деревьями ...

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


Make_Binary_Tree(&BTree, n);//вызов функции создания дерева
Print_BinaryTree(BTree, l)//печать на экран дерева
Rififi вне форума Ответить с цитированием
Старый 03.04.2012, 00:38   #3
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

PS. Посмотрел код внутри make_binary_tree...
учитывя что

BinaryTree* BTree = NULL;

а потом

ptr = Node;
while (*ptr != NULL) {

это жесткач. :D
Rififi вне форума Ответить с цитированием
Старый 03.04.2012, 01:40   #4
Blondy
Участник клуба
 
Аватар для Blondy
 
Регистрация: 07.07.2009
Сообщений: 1,385
По умолчанию

Спасибо Вам большое! Я просто действительно не очень в указателях, тем более в многозвездочных))

И скажите пожалуйста, что с Вашей точки зрения неправильно с узлами - ведь мы создаем вначале пустое дерево
Код:
BinaryTree* BTree = NULL;
и добавляем в него элементы вручную. Но так как в дальнейшем в программе память не очищается мы уже в готовое дерево (созданное до этого) можем уже добавлять элементы - поэтому здесь в коде и проверка на то, что указатель не указывает на пустое дерево.

Или я неправильно интерпетирую код?
"Все мы жаждем чудес. Чисто человеческое свойство." Carl Sagan

Последний раз редактировалось Blondy; 03.04.2012 в 01:44.
Blondy вне форума Ответить с цитированием
Старый 03.04.2012, 08:14   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
BinaryTree**
Никак не могу понять - зачем указатель на указатель?
Цитата:
Make_Binary_Tree(BinaryTree* BTree, n);//вызов функции создания дерева
Print_BinaryTree(BinaryTree BTree, l)//печать на экран дерева
Так. Тут тоже смусченья - Ты прямо внутри параметров объявила новую локальную переменную BTree.
Соответственно именно над ней пройдут операции. И за пределами функции она существовать не будет.
А в Print_BinaryTree(BinaryTree BTree, l) ты обьявляешь еще одну опятьтаки локальную переменную, но уже для Print_BinaryTree. Так что Rififi дело говорит.
Другое дело если бы ты приводила типы:
Код:
Make_Binary_Tree((BinaryTree*) BTree, n);//вызов функции создания дерева
Print_BinaryTree((BinaryTree) BTree,  l)//печать на экран дерева
Тогда бы работа велась с глобальной переменной
Но в данном случае это не нужно.
Цитата:
void Make_Binary_Tree(BinaryTree** Node, int n) //создание дерева
Еще Куестион - этим ты создаешь отдельную ветку древа, так? Само древо плавно превращается в... список двунаправленный.

Далее. Я никак не могу взять в толк, как же у тебя эта ветка изначально создается.
Смотри: ты объявила переменку:
Код:
BinaryTree* BTree = NULL;
Зачучмительно. Она пуста, тоже неплохо.
И далее ее передаешь в функцию создания древа:
Код:
void Make_Binary_Tree(BinaryTree** Node, int n) //создание дерева
{
  BinaryTree** ptr;//вспомогательный указатель
  srand(time(NULL)*1000);
  while (n > 0) {
    ptr = Node;
    while (*ptr != NULL) {
Здесь сразу ptr получает значение из параметра, а оно на первом этапе у тебя равно NULL, поскольку ты в него пихаешь BTree, изначально нулем проинициализированное.
Соответственно внутренний цикл сразу проскакивает на
Код:
    (*ptr) = new BinaryTree();
    cout << "Введите значение ";
    cin >> (*ptr)->Data;
    n--;
Тоже неплохо, здесь создаем новую ветку древа, наполняем ее фитофторозом с клавиатуры. Классно, но... Далее внешний цикл переходит на новую итерацию, а в нем первым же оператором будет... что? Ась?
Правильно:
Код:
ptr = Node;
Который все твои старания ((*ptr) = new BinaryTree() приведет к пшику, опять подставив в prt NULL.
Опять внутренний цикл пропустит свою отработку, опять ты выйдешь на (*ptr) = new BinaryTree();
получив таким образом простой динамический список. Причем как я понимаю, элементы этого списка друг с другом не связаны, поскольку нигде не увидел я работы с полями
Код:
       BinaryTree* Left; //указатель на левого потомка
       BinaryTree* Right;//указатель на правого потомка
I'm learning to live...

Последний раз редактировалось Stilet; 03.04.2012 в 08:17.
Stilet вне форума Ответить с цитированием
Старый 03.04.2012, 13:18   #6
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Blondy

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

Интересная особенность современного C++ - это то, что на нем возможно создавать программы, в "стиле Java/C#", то есть не используя голые указатели вообще. Недостатком данного подхода является более высокий порог вхождения, необходимость поднять значительно больше информации и ознакомиться со стандартной библиотекой шаблонов на уровне немного поболшем чем "ой, простите, я тут мимо проходила" :D

так напримре, эта уродливая запись на "Си с классами"

void Make_Binary_Tree(BinaryTree** Node, int n);

переписывается на C++

std::shared_ptr<BinaryTree> Make_Binary_Tree(int n);
Rififi вне форума Ответить с цитированием
Старый 03.04.2012, 16:14   #7
Blondy
Участник клуба
 
Аватар для Blondy
 
Регистрация: 07.07.2009
Сообщений: 1,385
По умолчанию

Дорогой Rififi, к сожалению, фокусы без указателей не удасться осуществить(( Я знаю что в С++ и вектора есть, и масса всего. Но нас туркают "мануалом", никаких готовых библиотек - типа, чтобы мы имели представление, ознакомить все хотят нас... а от этого еще больше путаницы. Уж лучше бы действительно дали возможность пользоваться готовыми шаблонами - вон, в C# есть и очереди, и стеки и двунаправленные списки и не надо ничего выдумывать.
"Все мы жаждем чудес. Чисто человеческое свойство." Carl Sagan
Blondy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как вызвать функцию из класса ? Silly Student Общие вопросы C/C++ 2 13.10.2011 20:07
Как в Visual Studio 2010 вызвать функцию, находящуюся в файле .cpp, из Form1.h ? MrRockchip Общие вопросы C/C++ 0 20.02.2011 17:37
Как вызвать функцию из юнита? Des Общие вопросы Delphi 5 06.11.2010 12:47
Не могу правильно вызвать функцию md5 TwiX Общие вопросы C/C++ 3 18.03.2010 22:23
Как вызвать функцию? blackstersl Общие вопросы Delphi 10 07.06.2009 19:22