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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача в функции структур по указателям, Испытываю значительные трудности 
:(
    Опции темы
Him
  Дата 10.5.2009, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Добрго Вам времени суток!

Помогите разобраться с программой. Вот ее код на языке СИ (Borland СИ):
Код
// Разработать программу слияния двух стеков, содержащих
// возрастающую последовательность целых положительных чисел,
// в третий стек так, чтобы его элементы располагались
// также в порядке возрастания.


#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

//=== *** === *** === *** === *** ===
struct stack
   {
       char cifra;
       struct stack *NextPtr;
   };

typedef stack Stack;
typedef Stack *StackPtr;

struct stack m1, *p1 = &m1;
struct stack m2, *p2 = &m2;
struct stack m3, *p3 = &m3;
struct stack m4, *p4 = &m4;


// --------------------------------------------
void Push (StackPtr *BeginPtr, char znachenie)    // внесение цифр в стек
   {
       while (znachenie != ".")
       {
         StackPtr NewPtr;
         NewPtr = (Stack*)malloc(sizeof(Stack));

       if (NewPtr != NULL)
          {
              NewPtr->cifra = znachenie;
                NewPtr->NextPtr = (*BeginPtr);
              (*BeginPtr) = NewPtr;
          }
          else
             printf("Ne mogu vvesti znachenie v stack");
        }
   }


// --------------------------------------------
char Pop(StackPtr *BeginPtr)     // удаление значения из стека
   {
       char popznachenie;
       StackPtr tempPtr;
       tempPtr = (*BeginPtr);
       popznachenie = (*BeginPtr)->cifra;
       (*BeginPtr) = (*BeginPtr)->NextPtr;
       free(tempPtr);

       return popznachenie;
   }


// --------------------------------------------
   void main()
      {
          int znachenie_1, znachenie_2;
          printf("Dlya ostanovki zikla vvoda vvedite tochku");
          printf("Vvedite zifru v 1-y stack");
          scanf("%d", &znachenie_1);
            Push (*p1 , znachenie_1);

          printf("Vvedite zifru vo 2-y stack");
          scanf("%d", &znachenie_2);
          Push (*p2 -> BeginPtr, znachenie_2);

          while (((*p1 -> BeginPtr) && (*p2 -> BeginPtr)) != NULL)
             {
                 if ((*p1 -> BeginPtr) == NULL)       // если первый стек пустой
                    Push (*p3 -> BeginPtr, Pop(*p2 -> BeginPtr));  // внести в 3-й содержимое 2-го стека
                 if ((*p2 -> BeginPtr) == NULL)      //если второй стек пустой
                    Push (*p3 -> BeginPtr, Pop(*p1 -> BeginPtr));  // внести в 3-й содержимое 1-го стека


                 if ((Pop(*p1 -> BeginPtr)) >= (Pop(*p2 -> BeginPtr)))  // если удаляемое значение 1-го стека >= знач. 2-го стека
                   {
                      Push (*p3 -> BeginPtr, Pop(*p1 -> BeginPtr));  // записать в 3-й сперва из 1-го стека
                      Push (*p3 -> BeginPtr, Pop(*p2 -> BeginPtr));  // затем записать в 3-й из 2-го стека
                   }
                 else
                   {
                      Push (*p3 -> BeginPtr, Pop(*p2 -> BeginPtr));  // записать в 3-й сперва из 2-го стека
                      Push (*p3 -> BeginPtr, Pop(*p1 -> BeginPtr));  // затем записать в 3-й из 1-го стека
                   }
             }

          // Извлечь из 3-го и внести в 4-й, т.е. менять порядок элементов в стеке

          while (*p3 -> BeginPtr != NULL)   // пока 3-й стек не пустой
             Push (*p4 -> BeginPtr, Pop(*p3 -> BeginPtr);   // извлечь из 3-го и внести в 4-й стек
      }




У меня возникли трудности с переносом в функции указателей на структуры и вставляемые элементы.
Составлял программу пользуясь различной литературой, вот нестыковки и получаются.

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

Помогите откорректировать программу.

PM MAIL   Вверх
bsa
Дата 11.5.2009, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Функция, которая возвращает указатель на целое:
Код
int* myProc();
Функция, которая принимает указатель на float в качестве параметра:
Код
void myProc(float *param);
Функция, которая принимает в качестве параметра указатель на указатель на целое:
Код
void myProc(int **param);
Пользуются ей обычно так:
Код
int *x;
myProc(&x);
Предполагается, что myProc изменит значение указателя, т.е. если х указывал на некую переменную y, то будет, возможно, указывать на z - зависит от функции.
В принципе, можно последную функцию описать так (ничего не изменится):
Код
typedef int *IntPtr;
void myProc(IntPtr *param);
Использовать ее можно точно также, а можно и так:
Код
IntPtr x;
myProc(&x);
Что по сути, одно и тоже.
PM   Вверх
Him
Дата 13.5.2009, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



bsa, 
В принципе мне понятно то, что Вы написали, но возникли некоторые вопросики.

Я использовал примеры из готового сборника, а там 
Код
struct stack
   {
       char cifra;
       struct stack *NextPtr;
   };


   typedef stack Stack;
   typedef Stack *StackPtr;



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

А второе, зачем вводить функцию принятия адреса значения, например
Код
int* myProc();


если это реализовано
Код

          int znachenie_1, znachenie_2;
          printf("Dlya ostanovki zikla vvoda vvedite tochku");
          printf("Vvedite zifru v 1-y stack");
          scanf("%d", &znachenie_1);


По логике вещей я должен этот адрес 
Цитата
&znachenie_1
  ввести в функцию, например Push, а вторым параметром мне надо внести само значение, но тут запутался, что конкретно вносить, ведь у меня есть только адрес значения 
Цитата
&znachenie_1
 , как же тогда предавать, и что именно.
Помогите в этом моменте, пожалуйста.

Это сообщение отредактировал(а) Him - 13.5.2009, 09:45
PM MAIL   Вверх
math64
Дата 13.5.2009, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 12
Всего: 72



Push() вставляет в стек пока не  кончится память
Pop() не проверяет есть ли что в стеке
PM   Вверх
Him
Дата 13.5.2009, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



math64, 
Спасибо Вам за ответ, но этот момент, что
Цитата

Push() вставляет в стек пока не  кончится память
Pop() не проверяет есть ли что в стеке
 
я понимаю, меня интересует конкретное назначение подмены 
Код

   typedef stack Stack;
   typedef Stack *StackPtr;

и как будет выглядеть код без этой подмены.
PM MAIL   Вверх
zim22
Дата 13.5.2009, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Him @  13.5.2009,  17:29 Найти цитируемый пост)
и как будет выглядеть код без этой подмены.

вместо Stack будет stack
вместо StackPtr будет Stack*


--------------------
PM MAIL   Вверх
Him
Дата 24.5.2009, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо всем, но, к сожалению, пример не решен.

 ИЗМЕНЯЮ ВОПРОС.

ЭТО ЭТО BORLAND C++ (v3.0-3.1)

В даном случае надо просто внести в стек данные типа int и вывести на экран (это я просто часть задания взял для рассмотрения), вот код:

Код

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

//=== *** === *** === *** === *** ===
struct stack
   {
       int cifra;
       struct stack *NextPtr;
   };

typedef stack Stack;
typedef Stack* StackPtr;

struct stack m1, *p1 = &m1;


// --------------------------------------------
void Push (StackPtr *BeginPtr, int znachenie)    // внесение цифр в стек

   {
         StackPtr NewPtr;
         NewPtr = (Stack*)malloc(sizeof(Stack));

       if (NewPtr != NULL)
          {
              NewPtr->cifra = znachenie;
            NewPtr->NextPtr = (*BeginPtr);
              (*BeginPtr) = NewPtr;
          }
          else
             printf("Ne mogu vvesti znachenie v stack");

   }


// --------------------------------------------
   void main()
      {
          int znachenie_1;
          printf("Dlya ostanovki zikla vvoda vvedite tochku");
          printf("Vvedite zifru v 1-y stack");
          scanf("%d", &znachenie_1);

        while (znachenie_1 != '.')
           Push (*p1 , znachenie_1);
        printf("%d", znachenie_1);

      }





Однако, при компиляции появляются сообщения:

Cannot convert 'stack' to 'stack * *'

Type mismatch in parametrer 'BeginPtr' in call to 'Push(stack * *,int)'


Помогите мне, пожалуйста, исправьте ошибки.
ЭТО BORLAND C++ (v3.0-3.1)


Это сообщение отредактировал(а) Him - 24.5.2009, 09:54
PM MAIL   Вверх
Dmi3ev
Дата 24.5.2009, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 13
Всего: 41



Цитата

void Push (StackPtr *BeginPtr, int znachenie)

здесь ты объявил BeginPtr так
а передаешь
Цитата

Push (*p1 , znachenie_1);

а p1 объявлен как
Цитата

struct stack m1, *p1 = &m1;


Цитата

StackPtr *BeginPtr

не вникал особо в суть задачи, но может это вот так надо объявить
Цитата

StackPtr BeginPtr

?

Это сообщение отредактировал(а) Dmi3ev - 24.5.2009, 10:08


--------------------

PM MAIL   Вверх
Him
Дата 24.5.2009, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Dmi3ev, 
Да нет, здесь *BeginPtr должен быть ссылкой на начало первого элемента стека,  куда же тогда вносить значения ...

Я действительно запутался с этими объявлениями.
Пример скомпоновывал из разных сборников иметодичек, поэтому и путаница с этими обявлениями.
На словах понимаю, что делать, а вот реализовать не могу.
PM MAIL   Вверх
andrew_121
Дата 24.5.2009, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

Репутация: 10
Всего: 33



Him, Хотел помочь...но похоже, тот кто писал этот код - Гений...епс smile  smile  smile  smile 
Не понятно для чего столько тайпдефоф.
В 19-ой строке, ты передаешь аргумент по указателю на указатель, потом разименовываешь его...для чего? smile 
Кароче компилится. Ошибок нет. А работает или нет...хз... Лучше перепиши код по человечески, а не по принципу адской головоломки.
Код


#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <locale.h>

//=== *** === *** === *** === *** ===

struct stack {
    int cifra;
    struct stack *NextPtr;
};

typedef stack Stack;
typedef Stack *StackPtr;

//=== *** === *** === *** === *** ===

struct stack m1;
StackPtr p1 = &m1;

//=== *** === *** === *** === *** ===

void Push (StackPtr BeginPtr, int znachenie)    // внесение цифр в стек
    StackPtr NewPtr;
    NewPtr = (StackPtr)malloc(sizeof(Stack));
    if (NewPtr != NULL) {
        NewPtr->cifra = znachenie;
        NewPtr->NextPtr = (BeginPtr);
        (BeginPtr) = NewPtr;
    } else {
        printf("Ne mogu vvesti znachenie v stack");
    }
}

//=== *** === *** === *** === *** ===

int main() {
    int znachenie_1;

    setlocale(LC_ALL, "Russian");
    
    printf("Для остановки цикла ввода, введите точку\nВведите первое число...\n");
    scanf("%d", &znachenie_1);
    
    while (znachenie_1 != '.') {
        Push(p1 , znachenie_1);
    }
    
    printf("%d", znachenie_1);
    
    return 0;
}

//=== *** === *** === *** === *** ===




--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Dmi3ev
Дата 24.5.2009, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 13
Всего: 41



Цитата

Да нет, здесь *BeginPtr должен быть ссылкой на начало первого элемента стека

ссылкой?  smile 
Him, просто как-то странно, что ты передаешь одно, а принимаешь другое... хз, по-моему...

Добавлено через 3 минуты и 41 секунду
andrew_121, ты ваще как-то по своему это воспринял  smile Я не так думал... Хотя я не вникал в суть, повторюсь, так что карты в руки вам рябята. 
зы
если все так и должно быть, то какого не компилится, может потому, что так не должно быть?


--------------------

PM MAIL   Вверх
Him
Дата 24.5.2009, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



andrew_121, 

На счет Typedef-ов я согласен, сам не понял половину, мне бы лучше простой код, но это у нас в методичке препод так написал.
Вот и мучаюсь.
Въехать толком не получается.
Теория понятна (более-менее), а реализация - завал.

Запустил, только еще больше ошибок наделалось:
Compiling PR0B3-2.CPP:

Error PR0B3-2.CPP 27: Declaration syntax error
Error PR0B3-2.CPP 28: Type name expected
Error PR0B3-2.CPP 28: Cannot conuert 'stack *' to 'int'
Error PR0B3-2.CPP 29: Declaration terminated incorrectly
Error PR0B3-2.CPP 36: Unexpected

PM MAIL   Вверх
Dmi3ev
Дата 24.5.2009, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 13
Всего: 41



andrew_121 потому что невнимательный в функции пуш в начале нет скобки...

Добавлено через 54 секунды
в 28 круглые скобки убери... вроде они там лишние...


--------------------

PM MAIL   Вверх
andrew_121
Дата 24.5.2009, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

Репутация: 10
Всего: 33



Цитата(Dmi3ev @  24.5.2009,  10:43 Найти цитируемый пост)
andrew_121 потому что невнимательный в функции пуш в начале нет скобки...

Я его сначала скомпилил, а потом отформатировал. smile 
Him, Сорри...

Добавлено через 1 минуту и 48 секунд
Dmi3ev, Хорош критиковать. Я вот всю ночь кодил, аж мозг кипит. Вот пытаюсь постепенно нагрузку понизить. Ну как в спорте...знаешь?
Потому что уснуть не получается. smile

Добавлено через 9 минут и 5 секунд
Цитата(Dmi3ev @  24.5.2009,  10:43 Найти цитируемый пост)
в 28 круглые скобки убери... вроде они там лишние...

Это еще по лучше того топика с диаметром окружности в трехмерном пространстве.

Dmi3ev, Слушай. Расскажи ка ты лучше мне как создать СВН репозиторий. У меня есть ФТП. А?

Добавлено через 10 минут и 48 секунд
Him, Еще мой код может не работать у тябя из-за того что я кожу под Лином. Шутка.
P/S/
Пора спатки...


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Him
Дата 24.5.2009, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



andrew_121, 

Исправил все, запустил, ввел первую цифру (1), так она зациклилась на сообщении "Ne mogu vvesti znachenie v stack" 

В чем проблем может быть?

Исправил, 
Код

    while (znachenie_1 != '.') {
        Push(p1 , znachenie_1);
        printf("%d", znachenie_1);
    }


так она показала один раз эту цифру и снова бесконечно по экрану "Ne mogu vvesti znachenie v stack"...

Это сообщение отредактировал(а) Him - 24.5.2009, 11:12
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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