Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 5.00
Krist_ALL
9 / 9 / 0
Регистрация: 01.02.2010
Сообщений: 317
#1

Указатель на указатель - разница способов - C++

14.03.2010, 14:18. Просмотров 1212. Ответов 18
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
int a =5;
int *b = &a;
 
 
 
int **e =&b;  //первый способ
//Нужно писать столько * скока указателей..
 
 
int *f = b; //Втрой способ
второй проще..
зачем тогда есть первый?

и как сделать укзатель на указатель на указатель?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.03.2010, 14:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатель на указатель - разница способов (C++):

Указатель или ссылка на указатель. В чем разница? - C++
Есть вопрос про указатели и ссылки на указатели :scratch: Хочу в функциях f1() и в f2() динамически выделить память и возвратить этот...

Как получить ссылку на указатель или указатель на указатель в массиве? - C++
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения указателей, передаваемых в функцию. Если...

Функция, получающая указатель на обычную функцию, получает указатель на метод класса - C++
Здравтсвуйте. Имеется вопрос по указателям на методы класса. Допустим, есть функция( f ), которая принимает указатель на функцию и...

Функция, принимающая указатель и число байт и выделяющая память под указатель - C++
Здравствуйте. Задача легкая, но почему-то завис Нужно написать функцию, принимающую указатель и число байт и выделяющую память под...

Как правильно удалять выделенную память под указатель на указатель? - C++
есть код #include <iostream> #include <conio.h> #include <stdlib.h> #include <time.h> using namespace std; void sort_1(const...

Реализация двоичных деревьев поиска: Зачем в параметрах функции используется указатель на указатель - C++
Всем привет, встретил в книге такой пример добавления узла в дерево: typedef struct tree { int data; tree *left, *right,...

18
R0mm
Псевдо программист
192 / 113 / 15
Регистрация: 19.09.2009
Сообщений: 303
14.03.2010, 14:26 #2
Krist_ALL, "второй способ" это не указатель на указатель, я присвоить значению указателя f значение b

первый способ единственный
0
Krist_ALL
9 / 9 / 0
Регистрация: 01.02.2010
Сообщений: 317
14.03.2010, 14:43  [ТС] #3
C++
1
2
3
4
int **e =&b; //5
 
 
int *f = b; //5
0
Krist_ALL
9 / 9 / 0
Регистрация: 01.02.2010
Сообщений: 317
15.03.2010, 14:57  [ТС] #4
int a = 5;

Первый способ
int *b = &a;
int *c = b;
int *d = c;

ВТорой

int *b = &a;
int **c = &b;
int ***d = &c;

первый ведь удобнее.
и не надо тучу * писать..
или я не прав?
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
15.03.2010, 15:11 #5
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Ты не прав. Это два разных способа, и используются они в разных случаях (конечно же, в твоем случае второй способ не используется, как нерациональный)
Первый способ. Ты объявляешь целую переменную a, потом объявляешь указатель b на целый тип, и инициализируешь его адресом a (с помощью операции взятия адреса). Теперь в переменной b хранится адрес a. Потом ты объявляешь еще один указатель c на целый тип, и инициализируешь его не адресом указателя b, а значением, которое он хранит-адресом а. Остальные указатели объявляются и инициализируются аналогично. Теперь, чтобы получить доступ к значению, которое храниться в a, например, с помощью указателя b, тебе нужно совершить однократную операцию разыменования указателя(например, *b=19 - и в переменной a будет храниться уже значение 19).
Второй способ. c - это уже указатель на указатель на целый тип, и он хранит уже не адрес a, а адрес указателя b. Соответственно, d - это указатель на указатель на указатель на целый тип, и чтобы изменить значение a с помощью указателя d, тебе нужно применить три раза операцию разыменования (***d=19). (*d==c==&b==&&a, **d==b==&a, ***d==a - это для наглядности )
PS. Здесь и ответ на твой вопрос:
Цитата Сообщение от Krist_ALL Посмотреть сообщение
и как сделать укзатель на указатель на указатель?
2
Krist_ALL
9 / 9 / 0
Регистрация: 01.02.2010
Сообщений: 317
15.03.2010, 15:23  [ТС] #6
Это я понимаю)
ав каких случаях первый способ рационален а когда второй.
в каких ситуациях?
0
Evg
Эксперт CАвтор FAQ
18248 / 6373 / 438
Регистрация: 30.03.2009
Сообщений: 17,643
Записей в блоге: 28
15.03.2010, 15:26 #7
Цитата Сообщение от Krist_ALL Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
int a =5;
int *b = &a;
 
 
 
int **e =&b;  //первый способ
//Нужно писать столько * скока указателей..
 
 
int *f = b; //Втрой способ
второй проще..
зачем тогда есть первый?

и как сделать укзатель на указатель на указатель?
Сделай printf ("%d", **e); и printf ("%d", **f);
Увидишь, что второй код - вовсе не то, что ты думал

Добавлено через 1 минуту
Цитата Сообщение от Krist_ALL Посмотреть сообщение
ав каких случаях первый способ рационален а когда второй.
Второго способа нет, потому как он делает совсем не то
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
15.03.2010, 15:27 #8
Evg, ну я же написал - для наглядности
0
Evg
Эксперт CАвтор FAQ
18248 / 6373 / 438
Регистрация: 30.03.2009
Сообщений: 17,643
Записей в блоге: 28
15.03.2010, 15:28 #9
Цитата Сообщение от Nameless One Посмотреть сообщение
Evg, ну я же написал - для наглядности
Я понял, но не сразу Удалил
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
15.03.2010, 15:44 #10
Цитата Сообщение от Krist_ALL Посмотреть сообщение
ав каких случаях первый способ рационален а когда второй.
Вопрос не в том, когда рационален один способ, а когда второй. Они используются для разных целей.
Начнем с того, что в C/C++ массивы реализованы с помощью указателей:
C++
1
2
int a[5];//a - указатель на первый элемент массива
         //a+1 - указатель на второй элемент массива и т.д.
Таким образом, записи a[0] и *(a+0), a[4] и *(a+4) - аналогичны. Когда ты используешь многомерные массивы (т.е. с размерностью больше единицы), ты уже используешь указатели на указатели на указатели... К примеру, двумерный массив типа int - это указатель на указатель на тип int.
Без указателей на указатели не обойтись, если ты хочешь динамически выделить память под многомерный массив:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
int main()
{
    //Выделение памяти под двумерный массив
    int** parr=new int*[2];
    for(size_t i=0; i<2; ++i)
    {
        parr[i]=new int[2];
        for(size_t j=0; j<2; ++j)
            parr[i][j]=i+j;//Доступ по индексу
    }
    for(size_t i=0; i<2; ++i, std::cout << std::endl)
        for(size_t j=0; j<2; ++j)
            std::cout << *(*(parr+i)+j) << " ";//Доступ через операцию разыменования
    //Освобождение памяти
    for(size_t i=0; i<2; ++i)
        delete[] parr[i];
    delete[] parr;
    system("pause");
    return 0;
}
Сначала ты выделяешь память под массив строк, потом для каждой строки ты выделяешь память под массив ее элементов
0
Genius Ignat
1237 / 775 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
15.03.2010, 15:57 #11
Двойной указатель используется для передачи простого указателя по адресу.
Могу не большой пример привести: добавление на вершину стека:
C++
1
2
3
4
5
6
void push(Node **top,int d){
Node *p = new Node;
p->d=d;
p->next=(*top);
(*top)=p;       //в переданном указателе меняется значение: теперь он ссылается на другую память.
}
Здесь передается указатель на вершину стека, его значение(указателя) меняется в этой функции.
1
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
15.03.2010, 16:06 #12
Genius Ignat, пример, конечно, наглядный, но что нам мешает передавать не адрес указателя, а сам указатель, и не применять лишних операций разыменования?
0
Krist_ALL
9 / 9 / 0
Регистрация: 01.02.2010
Сообщений: 317
15.03.2010, 17:14  [ТС] #13
а как передавать не адрес указателя, а сам указатель?
0
Nameless One
Эксперт С++
5775 / 3425 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
15.03.2010, 17:18 #14
C++
1
2
3
4
5
6
void push(Node *top,int d){
Node *p = new Node;
p->d=d;
p->next=top;
top=p;       
}
0
Evg
Эксперт CАвтор FAQ
18248 / 6373 / 438
Регистрация: 30.03.2009
Сообщений: 17,643
Записей в блоге: 28
15.03.2010, 18:02 #15
Цитата Сообщение от Krist_ALL Посмотреть сообщение
а как передавать не адрес указателя, а сам указатель?
C
1
2
3
4
5
6
7
8
9
10
11
/* Передача указателя */
extern void func (int *p);
...
int *ptr;
func (ptr);
 
/* Передача адреса указателя */
extern void func (int **p);
...
int *ptr;
func (&ptr);
1
15.03.2010, 18:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.03.2010, 18:02
Привет! Вот еще темы с ответами:

Указатель на указатель, функции для создания новых массивов? - C++
Всем привет! У меня в коде есть несколько новых массивов, чтобы не повторяться я создам функцию которая будет выделять память под новые...

Функция принимает указатель на void и возвращает указатель на int - C++
Запишите прототип функции, которая принимает указатель на void и возвращает указатель на int.

Объяснить работу функции, возвращающей указатель на указатель на char - C++
Добрый день! Сможете объяснить что означает запись char **InputFile(int &amp;strings);? Почему именно двойное **? Буду очень благодарна...

Передача умного указателя в функцию принимающую указатель на указатель - C++
Итак имеется функция со следующим параметром: HRESULT __stdcall Function(SomeClass **param); В случае, когда создаём обычный...


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

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

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