Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
29 / 6 / 0
Регистрация: 20.02.2016
Сообщений: 1,078
1

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

27.03.2017, 20:38. Просмотров 393. Ответов 5
Метки нет (Все метки)

Доброго времени суток!
Рассматриваю пример (из Лафоре) сортировки массива указателей на объекты, для чего используются указатели на указатели. Всё понял, кроме одного момента

В строке 48
C++
1
order(pp + j, pp + k);
То есть, это уже адреса объектов. Почему там не стоят *pp+j,*pp+k?
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
#include <iostream>
#include <string>
using namespace std;
 
class person // некоторый человек
{
protected:
string name; // имя
public:
void setName() // установка имени
{ cout << "Введите имя: "; cin >> name; }
void printName() // показ имени
{ cout << endl << name; }
string getName() // получение имени
{ return name; }
}; 
 int main()
 {
void bsort(person**, int); // прототип функции
person* persPtr[100]; // массив указателей на person
int n = 0; // количество элементов в массиве
char choice; // переменная для ввода символа
do
{
persPtr[n] = new person; // создаем новый объект
persPtr[n]->setName(); // вводим имя
n++; // увеличиваем количество
cout << "Продолжаем ввод (y/n)?"; // спрашиваем, закончен ли ввод
cin >> choice;
}
while(choice == 'y');
cout << "\nНеотсортированный список:";
for(int j = 0; j < n; j++) // покажем неотсортированный список
persPtr[j]->printName();
bsort(persPtr, n); // отсортируем указатели
cout << "\nОтсортированный список:";
for(j = 0; j < n; j++) // покажем отсортированный список
persPtr[j]->printName();
cout << endl;
return 0;
} 
void bsort(person** pp, int n)
{
void order(person**, person**); // прототип функции
int j, k; // переменные для циклов
for(j = 0; j < n - 1; j++) // внешний цикл
for(k = j + 1; k < n; k++) // внутренний цикл
order(pp + j, pp + k); // сортируем два элемента
}
void order(person** pp1, person** pp2)
{
if((*pp1)->getName() > (*pp2)->getName()) // если первая строка больше второй,
{
person* tempptr = *pp1; // меняем их местами
*pp1 = *pp2;
*pp2 = tempptr;
}
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.03.2017, 20:38
Ответы с готовыми решениями:

Почему массив указателей на строки не указывает на адреса?
Почему в этом примере указатель типа char не указывает адрес, а хранит в себе строки? Пример: ...

Создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей
Задача: создать специфицированный шаблон функции, принимающей массив указателей на char и...

Почему адреса у указателей разные, несмотря на то, что они указывают на одну и ту же переменную?
Почему адреса у указателей разные, они же указывают на одну и туже переменную int main() {...

Список указателей на авторские объекты, я могу воспользоваться только первым его элементом. Почему?
Друзья! Короче создал ПРОСТОЙ класс всего с одним полем и функцией которая выводит значение этого...

5
922 / 623 / 292
Регистрация: 26.02.2015
Сообщений: 2,845
27.03.2017, 20:52 2
Цитата Сообщение от Fatmarmelad Посмотреть сообщение
C++
1
order(pp + j, pp + k);
Тут мы передаем в функцию order "адреса на адреса объектов". А в неё уже мы меняем местами адреса объектов.

Добавлено через 4 минуты
Можно переписать, например, так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void bsort(person** pp, int n)
{
    void order(person*, person*); // прототип функции
    int j, k; // переменные для циклов
    for (j = 0; j < n - 1; j++) // внешний цикл
        for (k = j + 1; k < n; k++) // внутренний цикл
            order(*(pp + j), *(pp + k)); // сортируем два элемента
}
void order(person* pp1, person* pp2)
{
    if (pp1->getName() > pp2->getName()) // если первая строка больше второй,
    {
        person* tempptr = pp1; // меняем их местами
        pp1 = pp2;
        pp2 = tempptr;
    }
}
Добавлено через 3 минуты
Просто в функции order вы обходите массив указателей на элементы класса Person. Если Вы напишите
C++
1
*pp+j
, то разыменуете указатель на указатель на объект класса (получится указатель на объект), и после этого увеличите значение. Получится белеберда.

Нужно сначала перейти на следующий элемент массива указателей, разыменовать его и передать в функцию. Либо же не разыменовывая передавать его в функцию order, которая сама этим займётся.

Надеюсь, я понятно объясняю.
0
29 / 6 / 0
Регистрация: 20.02.2016
Сообщений: 1,078
27.03.2017, 21:18  [ТС] 3
Nishen,
Я вот как понимаю. Если person** pp1 указатель на адрес указателя, то * pp1 адрес указателя объекта, а pp1 адрес объекта.
То есть ** pp1 - разыменовать указатель, * pp1 - разыменовать объект. Или это неправильно?
0
922 / 623 / 292
Регистрация: 26.02.2015
Сообщений: 2,845
27.03.2017, 21:24 4
Fatmarmelad, нет, **p1 - указатель на указатель, *p1 - указатель на объект, p1 - объект.

Иными словами, пусть у нас есть объект p1. Положим его по адресу 0x0001, к примеру (в 0х0001 лежит p1) - это будет *p1. Теперь значение указателя *p1 (0х0001) положим по адресу (0х0002) - это будет **p2.

Добавлено через 37 секунд
Цитата Сообщение от Fatmarmelad Посмотреть сообщение
разыменовать объект.
Ну, и выражаться так не верно. Разыменовывают не объекты, а указатели.
0
29 / 6 / 0
Регистрация: 20.02.2016
Сообщений: 1,078
27.03.2017, 22:16  [ТС] 5
Nishen, а как можно разыменовать **p2?
0
922 / 623 / 292
Регистрация: 26.02.2015
Сообщений: 2,845
27.03.2017, 22:40 6
Дважды применить к указателю операцию разыменования.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.03.2017, 22:40

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

Виртуальные функции (создать массив указателей на объекты трех классов)
Задание: создать массив указателей на объекты трех классов. Метод Show почему-то не...


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

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

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