Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
17 / 17 / 10
Регистрация: 14.06.2012
Сообщений: 151

Передача указателя в функцию

18.08.2015, 20:53. Показов 3092. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Прошу помощи, сижу уже пару часов читаю мануалы, но так и не смог до конца понять, что мне делать. Есть вот такой код:

menu.h
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
#ifndef MENU_H
#define MENU_H
 
#include <iostream>
#include <cstdlib>
 
using namespace std;
 
void menu(int&);
 
template <class T>
void secMenu(char[], int&, T *pArray);
 
template <class T>
void CreateArray(T *pArray, int &);
 
template <class T>
void ShowArray(T *pArray, int &iAmount);
 
void menu(int &choice)
{
    system("cls");
 
    cout << "1. INT Array.\n";
    cout << "2. DOUBLE Array.\n";
    cout << "3. CHAR Array.\n";
    cout << "4. Exit.\n";
 
    cout << "Input Your choice: ";
    cin >> choice;
}
 
template <class T>
void secMenu(char type[], int &choice, T *pArray)
{
    int iAmount(0);
 
    bool exit = false;
    while (!exit)
    {
        system("cls");
        cout << "1. Create " << type << " array\n";
        cout << "2. Show " << type << " array\n";
        cout << "3. Exit\n";
        cout << "\nYour choice: ";
        cin >> choice;
 
        switch (choice)
        {
        case 1: CreateArray(pArray, iAmount); break;
        case 2: ShowArray(pArray, iAmount); break;
        case 3: exit = true; delete[] pArray; pArray = NULL; break;
        default: system("cls"); cout << "Incorrect value!\n"; system("pause"); break;
        }
    }
}
 
template <class T>
void CreateArray(T *pArray, int &iAmount)
{
    system("cls");
    cout << "Input size of array: ";
    cin >> iAmount;
 
    if (pArray != 0)
    {
        delete[] pArray;
    }
    pArray = new T[iAmount];
 
    for (int i = 0; i < iAmount; i++)
    {
        system("cls");
        cout << "Input " << i + 1 << " element of array: ";
        cin >> pArray[i];
    }
 
    for (int i = 0; i < iAmount; i++)
    {
        cout << i + 1 << " element of array: ";
        cout << pArray[i] << "\n";
    }
    system("pause");
    system("cls");
}
 
template <class T>
void ShowArray(T *pArray, int &iAmount)
{
    for (int i = 0; i < iAmount; i++)
    {
        cout << i + 1 << " element of array: ";
        cout << pArray[i] << "\n";
    }
    system("pause");
    if (pArray == NULL)
    {
        system("cls");
        cout << "Array does not exist!\n";
        system("pause");
    }
    else
    {
        for (int i = 0; i << iAmount; i++)
        {
            cout << "Array element number " << i + 1 << ": " << pArray[i] << "\n";
        }
    }
    cout << "\n";
}
 
#endif MENU_H
main.cpp
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
#include <iostream>
#include <cstdlib>
 
#include "menu.h"
 
using namespace std;
 
int main()
{
    int choice(0);
    bool exit = false;
 
    int *pInt = NULL;
    double *pDouble = NULL;
    char *pChar = NULL;
 
    while (!exit)
    {
        menu(choice);
        switch (choice)
        {
        case 1: secMenu("INT", choice, pInt); break;
        case 2: secMenu("DOUBLE", choice, pDouble); break;
        case 3: secMenu("CHAR", choice, pChar); break;
        case 4: exit = true; break;
        default: system("cls"); cout << "Incorrect value!\n"; system("pause"); break;
        }
    }
    return 0;
}
Проблема в том, что у меня есть указатель int *pointer = 0; который я передаю в функцию void secMenu(char[], int&, T *pArray); внутри которой вызывается другая функция, в которую я опять же передаю тот указатель: void CreateArray(T *pArray, int &iAmount). Методом "тыка" выяснил, что выделенная память под динамический массив никак н привязывается к моему указателю. Пробовал вариации с T **pArray, не помогло, я явно что-то упускаю. Буду благодарен за помощь.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.08.2015, 20:53
Ответы с готовыми решениями:

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

Передача указателя на функцию
Доброго дня Форумчане. Хотелось бы узнать как вызывать функцию получив на нее указатель? пример class C1 { public: void...

Передача в функцию указателя
Почему плохо передавать в функцию указатель на строку или массив и возвращать указатель на строку или массив?

8
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
18.08.2015, 21:10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
 
void set(int** ptr)
{
    *ptr = new int[1];
    *(*ptr) = 10;
}
int main()
{
    int* ptr = new int(15);
    cout << *ptr << endl;
    delete ptr;
    set(&ptr);
    cout << *ptr << endl;
    delete ptr;
 
}
1
17 / 17 / 10
Регистрация: 14.06.2012
Сообщений: 151
18.08.2015, 21:23  [ТС]
Немного проясняется. Вопрос по синтаксису в такой ситуации:

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
#include <iostream>
using namespace std;
 
void prevSet(int** ptr) //Не могу понять синтаксис передачи в такой ситуации. :(
{
    /*
    */
    set(&ptr)
}
 
void set(int** ptr)
{
    *ptr = new int[1];
    cin >> ptr[0];
}
int main()
{
    int* ptr = new int(15);
    cout << *ptr << endl;
    delete ptr;
    prevSet(&ptr);
    cout << *ptr << endl;
    delete ptr;
}
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
18.08.2015, 21:53
Цитата Сообщение от XpertVision Посмотреть сообщение
Не могу понять синтаксис передачи в такой ситуации.
Передаётся указатель на указатель на тип int.
1
17 / 17 / 10
Регистрация: 14.06.2012
Сообщений: 151
18.08.2015, 21:58  [ТС]
castaway,

Я не корректно написал. Уточню вопрос. Я совсем не могу понят синтаксис передачи указателя в функцию из функции в которую его уже передали. И совсем уже молчу, про то как обратиться к его полям для записи и чтения переменных. В голове макароны как пытаюсь разобрать даже самый простой пример.
0
99 / 46 / 18
Регистрация: 09.08.2015
Сообщений: 367
18.08.2015, 22:47
Цитата Сообщение от XpertVision Посмотреть сообщение
Я не корректно написал. Уточню вопрос. Я совсем не могу понят синтаксис передачи указателя в функцию из функции в которую его уже передали. И совсем уже молчу, про то как обратиться к его полям для записи и чтения переменных. В голове макароны как пытаюсь разобрать даже самый простой пример.
Указатель это int который хранит в себе номер ячейки в ОЗУ. Указатель на указатель это когда в ячейке ОЗУ номер другой ячейки ОЗУ. В данном случае есть какой то массив ячеек в ОЗУ (расположены последовательно по номерам, так и работает адресная арифметика) в каждой ячейке которого номер другой ячейки.
ptr - переменная. &ptr - номер ячейки в ОЗУ записанный в переменной. *ptr - перейти по номеру записанному в переменной и взять оттуда данные.
Правда я давно на плюсах ничего не писал, мог что то подзабыть или напутать.
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
19.08.2015, 08:04
XpertVision, надо Вам, батенька, в указатели научиться.

Добавлено через 6 минут
Потому как без понимания работы указателей, будет у Вас одно расстройство.

Добавлено через 2 минуты
А по уму, возьмите, купите книжку по С++ для начинающих (вариант для бедных студентов - скачайте) и прочитайте главу про указатели. Делов на час - максимум.

Добавлено через 5 минут
Вариант для ленивых


Добавлено через 1 час 15 минут
Цитата Сообщение от XpertVision Посмотреть сообщение
void prevSet(int** ptr) //Не могу понять синтаксис передачи в такой ситуации.
XpertVision, в функцию передаётся указатель на указатель на тип int. Более простым языком: в функцию передаётся двумерный массив (матрица).

Добавлено через 5 минут
XpertVision, у любой функции должен быть прототип и определение.
Прототип пишется, чтобы дать компилятору информацию о:
  1. типе функции (типе возвращаемого значения)
  2. типе и количестве аргументов
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
#include <iostream>
using namespace std;
 
void prevSet(int** ptr);    //прототип функции prevSet()
 
 
void set(int** ptr);     //прототип функции set()
 
int main()
{
    int* ptr = new int(15);
    cout << *ptr << endl;
    delete ptr;
    prevSet(&ptr);    // вызов функции prevSet()
    cout << *ptr << endl;
    delete ptr;
    return 0;
}
 
void prevSet(int** ptr)    //определение функции prevSet()
{
    /*
    */
    set(&ptr);    // вызов функции set()
}
 
void set(int** ptr)    //определение функции set()
{
    *ptr = new int[1];
    cin >> ptr[0];
}
Добавлено через 7 минут
Иногда определение пользовательских функций помещают перед функцией main() - в Вашем коде именно так и сделано. И тогда эти определения выполняют также и роль прототипа (в таких случаях отдельно писать прототип не нужно).
2
2393 / 1913 / 763
Регистрация: 27.07.2012
Сообщений: 5,557
19.08.2015, 10:18
Лучший ответ Сообщение было отмечено XpertVision как решение

Решение

C++
1
2
3
4
5
6
7
void f(int * argPtr)
{
    argPtr = new int[10];
}
// ...
int * ptr = 0;
f(ptr);
Здесь функция f принимает копию указателя, выделяет память и записывает адрес выделенной памяти в эту самую копию. Исходный указатель ptr при этом остаётся равен предыдущему значению.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void f1(int *& argPtr)
{
    argPtr = new int [10];
}
 
void f2(int ** argPtr)
{
    *argPtr = new int[10];
}
 
int *ptr1, *ptr2;
f1(ptr1);
f2(&ptr2);
Здесь же функции f1 и f2 принимают соответсвенно ссылку на указатель и указатель на указатель, который передаётся в функцию. Стало быть память, которую они выделяют, они передают тому указателю, который передан в эти функции. f1 - по ссылке, т.е. не нужно никаких доп.действий при присваивании. В f2 же передаётся указатель на указатель, т.е. "верхний" указатель нужно разыменовать (*), чтобы получить достпуп к "нижнему" указателю, а в саму функцию нужно передать адрес указателя (&).

Добавлено через 1 минуту
ПС. Ну это если я правильно понял, в чём собственно проблема.
1
17 / 17 / 10
Регистрация: 14.06.2012
Сообщений: 151
19.08.2015, 11:18  [ТС]
John Prick, Вы поняли проблему лучше всех. =) Я понимаю, что передавая указатель через * мы получаем его копию, а ** как указатель на указатель и нужно "опуститься" на нужный нам уровень уже внутри функции через *. Проблема была в том, что я при таком раскладе не понимал синтаксис передачи указателя:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int *pointer = NULL;
 
void first(int **pointer)
{
   *pointer = new int;
   /*...*/
   second(*&pointer) - я всегда думал, что нужно "&*" - адрес указателя.
}
 
void second (int **pointer)
{
   *pointer = new int[2];
   *pointer[1] = 2;
}
ну и для чтения чтения-записи синтаксис не cin>>*pointer[i], а cin>>(*pointer)[i]; - разыменовываем указатель, а затем обращаемся к елементу массива.

Большое всем спасибо, надеюсь вопросов у меня больше не возникнет. =)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.08.2015, 11:18
Помогаю со студенческими работами здесь

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

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

передача указателя на функцию
Помогите исправить ошибку уже незнаю как быть В бивает ту ошибку error C2664: Generate: невозможно преобразовать параметр 2 из...

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

Передача указателя на функцию
Есть класс в котором: typedef void(*setChar)(int x, int y, wchar_t c); void Paint(setChar SetChar) В другом классе...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru