Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
НовыйПетрович
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 13
#1

Передача параметров функции - C++

19.05.2016, 22:12. Просмотров 589. Ответов 20
Метки нет (Все метки)

Не могу передать значение переменной функции. По идее все правильно, но она берет только последнее значение, а ещё может зациклиться.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <cstdlib>
#include <cmath>
const int numOfNumbers = 30;
int a = 0;
FILE *R;
int main(){
    int b[numOfNumbers];
 fillFile(); // Здесь всё работает.
    R = fopen("dataTo.txt","rb");
    if(R != NULL) {
        R = fopen("dataTo.txt", "rb");
        printf("fscanf\n");
        for(int j1 = 0; j1 < numOfNumbers; j1++){
            fscanf(R, "%i \n", &a);
            //fread(&a, sizeof(int), 1, R);            
            printf("%i ", a);
           root = add_node(root, a); // Здесь не работает. Берет только последнее значение из файла.
            //printf("%i *** ", a);
        }
    }
    printf("fread\n");
         for(int j = 0; j < numOfNumbers; j++) {
          //root = add_node(root, b[j]);
           // printf("%i ", b[j]);
            fread(&a, sizeof(int), 1, R);
         //    printf("%i ", a);
          root = add_node(root, a); // Здесь не работает. Да и числа совсем не из файла.
        //    add_node(a); // Так ничего не дает.
        }
        fclose(R);
   printResult(root);
    changeToPositive(root);
    printResult(root);
    printf("\nThe End of the program.\n");
    std::cin.get();
    return 0;
}
Добавлено через 1 минуту
Здесь только фрагмент. Остальное пока работает без сбоев.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.05.2016, 22:12
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Передача параметров функции (C++):

Передача параметров функции
Добрый день! Помогите, пожалуйста с передачей параметров по функциям. Как...

Передача параметров в функции
Здравствуйте Помогите, пожалуйста, разобраться с передачей параметров....

Передача параметров функции
доброго времени суток:) есть программа реализующая метод градиентного спуска....

Передача параметров функции в main()
Вот у меня есть две функции, которые в дальнейшем нужно вызвать в void main ()....

Передача параметров во виртуальные функции, перегрузка
нужна помощь. имеется абстрактный класс Base, объекты которого будут храниться...

Передача массивов в качестве параметров функции
Задав динамический двумерный массив вещественных данных (матрицу А размером...

20
nmcf
6245 / 5557 / 2527
Регистрация: 14.04.2014
Сообщений: 23,361
20.05.2016, 09:39 #2
Здесь ничего нет. Функцию свою проверяй.
0
НовыйПетрович
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 13
20.05.2016, 14:56  [ТС] #3
Так и здесь ничего нет! То, что ниже, ничем не отличается от других рабочих функций, а передаётся только последнее значение.
add_node(root, a);
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
TREE* add_node(TREE* root, int newNumber) {
    printf("Begin to add to binary tree.");
    if(root == NULL){
        root = (TREE *)malloc(sizeof(TREE));
        root->data.numberInStruct = newNumber;
        root->left = root->right = NULL;
        return root;
    }
    if(root->data.numberInStruct < newNumber)
        root->right = add_node(root->right, newNumber);
    else
        root->left = add_node(root->left, newNumber);
    return root;
}
Добавлено через 1 минуту
Что тут ещё можно проверить?

Добавлено через 3 минуты
Есть скрин с выводом. Программа компиллируется, запускается. Но в результате много надписей и мало чисел. Если не делать присваивание,
C++
1
root = add_node(root, a);
тогда в функцию не попадает даже это единственное число.
0
nmcf
6245 / 5557 / 2527
Регистрация: 14.04.2014
Сообщений: 23,361
20.05.2016, 16:39 #4
Как-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TREE* add_node(TREE* root, int newNumber)
{
    printf("Begin to add to binary tree.");
    if(root == NULL){
        root = (TREE *)malloc(sizeof(TREE));
        root->data.numberInStruct = newNumber;
        root->left = root->right = NULL;
        return root;
    }
    if(root->data.numberInStruct < newNumber)
        r = add_node(root->right, newNumber);
    else
        r = add_node(root->left, newNumber);
 
    return r;
}
0
НовыйПетрович
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 13
20.05.2016, 17:23  [ТС] #5
Посмотрите на вывод. а)В дерево ничего не попало, кроме последнего числа. б) Подпрограмма показа дерева работает нормально. в) Элементы в файл записались, и нормально выводятся.
Вот только в функцию добавления не попадают.
0
Миниатюры
Передача параметров функции  
НовыйПетрович
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 13
20.05.2016, 17:27  [ТС] #6
Причём, элементы не попадают в функцию добавления ни с помощью fscanf, ни fread. Распечатка элементов из файла показывает, что хоть одна из них, но прикручена верно, значит, считываем правильно, а добавляем неправильно.
0
nmcf
6245 / 5557 / 2527
Регистрация: 14.04.2014
Сообщений: 23,361
20.05.2016, 17:43 #7
Что значит "не попадают в функцию"? Такого не может быть. На момент вызова функции параметры верны? Из файла считываются?
0
НовыйПетрович
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 13
20.05.2016, 18:47  [ТС] #8
Я заполняю файл тридцатью элементами через переменную (для экономии памяти). Файл есть, элементы в нём тоже есть. На скрине вторая надпись "Print elements from file." Это проверка заполнения файла. Делаю тоже через переменную, как и заполнение. Это была подпрограмма fillFile(), и она работает. Далее открываю файл для заполнения уже дерева. Опять переменной присваиваю значение элемента файла на текущей итерации, а эту переменную отдаю подпрограмме add_node(root, a). Эта надпись "Begin to add to binary tree." - надпись в начале подпрограммы. Выводится 30 раз - обход дерева совершен. Но при вызове функции показа заполненного дерева - пустота. Значит, в дерево 30 раз записалось ничто. Если обход дерева нормально работает (судя по надписи "Begin to add to binary tree.", и файл не пустой, числа есть, значит, я что-то потерял на этапе передачи в функцию. Других предположений у меня нет. Выложить весь код?

Добавлено через 3 минуты
Вернее, при выводе дерева не пустота, а один элемент. В конце всех тридцати надписей "Begin to add to binary tree." выводит число, которое идёт последним в файле. Остальных нет, значит, потеряны при передаче. Не так ли?
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4377 / 2352 / 655
Регистрация: 18.10.2014
Сообщений: 4,002
20.05.2016, 19:29 #9
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Программа компиллируется, запускается.
Байки про "компиллируется, запускается" тут никому не интересны. Программа не компилируема, ибо никакого root у вас в коде нигде не определено.

Приводите осымысленный код, а не какие-то обрывки "по мотивам".

Цитата Сообщение от НовыйПетрович Посмотреть сообщение
...Это была подпрограмма fillFile(), и она работает. ... Но при вызове функции показа заполненного дерева - пустота. Значит, в дерево 30 раз записалось ничто. ... значит, я что-то потерял на этапе передачи в функцию. Других предположений у меня нет. Выложить весь код?
От этих теорий тоже мало пользы. Если вы не в состоянии осмысленно локализовать место ошибки, то другого выхода, кроме как "выложить весь код" нет.

Цитата Сообщение от nmcf Посмотреть сообщение
Как-то так:
Зачем? И чем это отличается от исходного варианта?
0
nmcf
6245 / 5557 / 2527
Регистрация: 14.04.2014
Сообщений: 23,361
20.05.2016, 20:06 #10
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
чем это отличается от исходного варианта
Возвращаемым значением.
0
НовыйПетрович
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 13
20.05.2016, 21:25  [ТС] #11
Весь код с внесёнными изменениями от nmcf, и я ещё поудалял лишнего:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <cstdlib>
#include <cmath>
const int numOfNumbers = 30;
int a = 0;
FILE *R;
typedef struct tag_data { // Через typedef для лучшей переносимости.
    int numberInStruct;
}DATA;
typedef struct tag_tree {
    DATA data;
    struct tag_tree* left;
    struct tag_tree* right;
}TREE;
TREE* root = NULL;
TREE* current = root;
TREE* add_node(TREE* root, int newNumber)
{
    printf("Begin to add to binary tree.");
    if(root == NULL){
        root = (TREE *)malloc(sizeof(TREE));
        root->data.numberInStruct = newNumber;
        root->left = root->right = NULL;
        return root;
    }
    if(root->data.numberInStruct < newNumber)
        root = add_node(root->right, newNumber);
    else
        root = add_node(root->left, newNumber);
    return root;
}
void fillFile() {
    printf("Begin to fill a file of data.\n");
    time_t t;
   // int b[numOfNumbers];
   R = fopen("dataTo.txt","wb");
   if(R != NULL) {
    srand(static_cast<unsigned int>(time(&t)));
    for(int i = 0; i < numOfNumbers; i++) {
        a = rand() % 10000 - 5000;
        fprintf(R, "%i \n", a);
    }
   fclose(R);
   printf("Print elements from file.\n");
   R = fopen("dataTo.txt", "rb");
   if(R != NULL){
       for(int j = 0; j < numOfNumbers; j++){
           fscanf(R, "%i \n", &a);
           printf("%i *** ", a);
       }
   }
    printf("End of recording data.");   
}
}
void changeToPositive(TREE* root) {
    current = root;
    while(current != NULL) {
            while(current->left->data.numberInStruct < 0){
            current->data.numberInStruct = fabs(current->data.numberInStruct);
            changeToPositive(root->left);
            changeToPositive(root->right);
        }
        current = root;
        while(current->right->data.numberInStruct < 0){
            current->data.numberInStruct = fabs(current->data.numberInStruct);
            changeToPositive(root->left);
            changeToPositive(root->right); 
        }
        
    }
}
void Show(TREE * &root){  // It`s work.
    //printf("Обход дерева в префиксной форме.\n");
    if(root == NULL) return;
    //while(root != NULL){
    if(root != NULL){
    std::cout<<root->data.numberInStruct<<std::endl;
    Show(root->left);    
    Show(root->right);
    }
}
void del_tree(TREE * root){
    while(root != NULL){
        del_tree(root->left);
        del_tree(root->right);
        delete root;
    }
}
int main()
{
    fillFile();
    R = fopen("dataTo.txt","rb");
   if(R != NULL) {
        for(int j1 = 0; j1 < numOfNumbers; j1++){
            fscanf(R, "%i \n", &a);
            //printf("%i ", a);
            root = add_node(root, a);
       }
   }
    fclose(R);
    Show(root);
    std::cout<<"changeToPositive\n";
    changeToPositive(root);
    Show(root);
    del_tree(root);
    root = NULL;
    printf("\nThe End of the program.\n");
    std::cin.get();
    return 0;
}
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4377 / 2352 / 655
Регистрация: 18.10.2014
Сообщений: 4,002
20.05.2016, 21:48 #12
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
с внесёнными изменениями от nmcf
Эти изменения не верны. Как раз таки изначально было правильно.

Заполнение и вывод дерева работают нормально (если убрать "изменения от nmcf").

В changeToPositive написана какая-то белиберда, которая успешно падает по доступу через нулевой указатель. В del_tree тоже написана белиберда.
0
nmcf
6245 / 5557 / 2527
Регистрация: 14.04.2014
Сообщений: 23,361
20.05.2016, 21:49 #13
Правильно, что функция возвращает тот же root, который получила? Ну если автор этого хотел.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4377 / 2352 / 655
Регистрация: 18.10.2014
Сообщений: 4,002
20.05.2016, 22:01 #14
Цитата Сообщение от nmcf Посмотреть сообщение
Правильно, что функция возвращает тот же root, который получила?
А кто сказал, что он тот же?

Перед вами стандартная, широко используемая идиома рекурсивной модификации дерева.

Вызывающий код должен знать только одно - функция возвращает новый корень поддерева. А будет ли он тем в данном конкретном вызове тем же самым или будет другим - это вызывающий код не касается. Сказано "новый" - значит новый. Задача вызывающего кода - получить и сохранить в правильное место новое значение корня поддерева.

В этой конкретной реализации значение будет меняться только при создании самого первого узла поддерева. После этого оно уже меняться не будет. А завтра, может быть, кто-то захочет и добавит перебалансировку поддерева при добавлении нового узла. И корень будет меняться более часто. Но вызывающий код об этом не должен беспокоиться.

Добавлено через 1 минуту
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В del_tree тоже написана белиберда.
Что в del_tree делает цикл while, который на второй итерации будет проверять некорректный (удаленный) указатель и доступаться через этот некорректный указатель - не ясно. В результате del_tree тоже падает.
0
nmcf
6245 / 5557 / 2527
Регистрация: 14.04.2014
Сообщений: 23,361
20.05.2016, 22:06 #15
В его первоначальной реализации функция вернёт новый корень, только когда дерево пустое. Я подумал, что он хочет получить указатель на новый элемент.
0
НовыйПетрович
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 13
21.05.2016, 22:40  [ТС] #16
1) То, что функция освобождения памяти не правильная мне говорили, но пока больше беспокоит не работающее заполнение.
2) Изначально задумано, что первый элемент, который попадает в дерево, становится корнем, и корень не меняется.
3) По заданию необходимо найти в дереве все отрицательные элементы и заменить их на модули. Конечно, после этого, скорее всего придётся перестраивать дерево. Над этим фрагментом тоже нужно поработать.
Только какой сейчас смысл исправлять другие подпрограммы, если функция добавления работает неправильно? Я сейчас закомментирую changeToPositive, del_tree, и что получим? - не рабочую программу. Добавление не работает.

Добавлено через 11 минут
changeToPositive ... успешно падает по доступу через нулевой указатель.
Здесь подробнее, пожалуйста.

В del_tree я хотел рекурсию. Сначала было через if:
C++
1
2
void del_tree(TREE * root){
    if(root != NULL){
Но мой личный астролог советует для работы с динамической памятью забыть про for, иногда про if, и использовать while. Где какой лучше пока не уяснил. Объясние, пожалуйста, это тоже.

Добавлено через 14 часов 59 минут
Расскажите лучше, почему если не сделать вот так:
C++
1
root = add_node(root, a);
то в дерево не попадает даже последнее число из файла.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4377 / 2352 / 655
Регистрация: 18.10.2014
Сообщений: 4,002
21.05.2016, 23:13 #17
Лучший ответ Сообщение было отмечено НовыйПетрович как решение

Решение

Цитата Сообщение от НовыйПетрович Посмотреть сообщение
2) Изначально задумано, что первый элемент, который попадает в дерево, становится корнем, и корень не меняется.
Именно так у вас и сделано.

Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Только какой сейчас смысл исправлять другие подпрограммы, если функция добавления работает неправильно? Я сейчас закомментирую changeToPositive, del_tree, и что получим? - не рабочую программу. Добавление не работает.
Что за ерунда? Это откуда вы такое взяли? Ваше добавление в его изначальной форме работает прекрасно. Никаких проблем с добавлением я не увидел - все добавляется и все выводится.

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

Цитата Сообщение от НовыйПетрович Посмотреть сообщение
Расскажите лучше, почему если не сделать вот так:
C++
1
root = add_node(root, a);
то в дерево не попадает даже последнее число из файла.
Ничего не понимаю. Что за сюрреалистический вопрос? Если вы не будете вызывать функцию добавления узлов в дерево, то они туда и не добавятся, разумеется. Вас это удивляет?

Добавлено через 11 минут
Вот ваш код - все прекрасно работает

http://coliru.stacked-crooked.com/a/c87c3f8485bc8ed6

Я только убрал странную манеру открывать файл в бинарном режиме (с чего это???), добавил закрытие файла там, где оно нужно (стр. 53) и перевод строки, там где он нужен (стр. 54). Идиотизмы, типа передачи указателя в функцию Show по ссылке (стр. 57) или двойной проверки этого указателя на NULL (стр. 58-59), я оставил нетронутыми.
0
НовыйПетрович
0 / 0 / 0
Регистрация: 16.05.2016
Сообщений: 13
22.05.2016, 14:39  [ТС] #18
Сюрреализм в том, что, если это
C++
1
root = add_node(root, a);
превратить вот в это,
C++
1
add_node(root, a);
то, не создаётся первый узел. Почему? В корень идёт 0, что ещё надо?

Спасибо. Пойду прикручу другие свистелки. Напишу ещё.
0
nmcf
6245 / 5557 / 2527
Регистрация: 14.04.2014
Сообщений: 23,361
22.05.2016, 14:41 #19
Цитата Сообщение от НовыйПетрович Посмотреть сообщение
то, не создаётся первый узел. Почему?
Потому что созданное возвращается функцией. Ты игнорируешь возврат и объект где-то в памяти остаётся.
0
НовыйПетрович
22.05.2016, 15:03  [ТС]     Передача параметров функции
  #20

Не по теме:

Хотел спасибо нажать. Параметры в функцию не попали.

Fatal error: Call to undefined function is_empty() in /home/cyberforum/data/www/cyberforum.ru/post_thanks.php on line 58

Так и должно быть?

0
22.05.2016, 15:03
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.05.2016, 15:03
Привет! Вот еще темы с ответами:

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

Передача массивов и параметров с одной функции в другую
Здравствуйте. Я пишу программу, она состоит из множества функций. И у меня...

Передача параметров функции по значению, ссылке и указателю
Вычислить F=f(a)-5f^3(sin(b/2))+1/f(1+c^4), де f(x)=3x^2-2x^2+7, при a=5.08,...

Передача массивов указателей в качестве параметров функции
Доброго времени суток, не компилится данный код. Ошибка возникает в функции...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru