Форум программистов, компьютерный форум CyberForum.ru

Указатели на указатель - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
22.04.2012, 04:17     Указатели на указатель #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
void print(char** p)
{
    while(*p)
    std::cout << *p++ << '\n'; //ps[0] а потом ps[1] ?
}
 
void main()
{
    std::cout << "Test string \n";
    char** ps = new char*[10];
    char* p = new char[256];
    std::cin >> p;
    *ps++ = p; //ps[0] = p ?
    char* k = new char[256];
    std::cin >> k;
    *ps = k; // ps[1] = k?
    print(ps);
    
}
Не работает такой пример.
Я пытался создать указатель на массив указателей
C++
1
char** ps = new char*[10];
далее записать 0 элементу массива указателей считаную строку
потом 1 элементу
при попытки вывести эти строки ошибка и выводится только последний элемент.
почему
C++
1
while(*p)
не прирывает функцию?
Почему не выводится первый элемент?
Спаибо за помошь )
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
22.04.2012, 05:36     Указатели на указатель #2
void print(char** p) не будет выводить с первого элемента, т.к. вы передаете в функцию указатель ps, который на момент передачи равен адресу ps[1]
Вот тут вы увеличиваете значение указателя, и он перестает указывать в начало
C++
1
*ps++ = p; //ps[0] = p ?
чтобы все получилось, нужно вызвать print так:
C++
1
print(--ps);
Подумайте почему)

А по поводу того, что
C++
1
while(*p)
не прерывает функцию... в скобках, после while, должно быть условие, а условие имеет знаки >,<,<=,>=,==,!=.
Если вы подразумеваете здесь условие *p!=NULL или *p!=0, то попробуйте найти место в программе, где элементу ps[2] присваевается 0 или NULL.

Добавлено через 10 минут
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>
 
void print(char** p)
{
    while(*p!=0)
        std::cout << *p++ << '\n'; //ps[0] а потом ps[1] ? теперь так
}
 
void main()
{
    std::cout << "Test string \n";
    char* s[10] = {0}; // теперь условие в 5-ой строке этого кода сработает
    // здесь не обязательно выделять память new
    char** ps = s;
    char p[256];
    std::cin >> p;
    *ps++ = p; //ps[0] = p ? да
    char k[256];
    std::cin >> k;
    *ps = k; // ps[1] = k? да
    ps = s; // возвращаем указатель в начало
    print(ps);
    // если выделяете new, то очищайте память при помощи delete
}
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
22.04.2012, 09:08     Указатели на указатель #3
Merovingian, тык. Но это скорей всего зависит от компилятора. Так что в случае ТС - ему просто повезло.
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
22.04.2012, 11:23  [ТС]     Указатели на указатель #4
Merovingian, Спасибо
а если бы я написал ввод через функцию и она возращала указатель на указатель
C++
1
char** new_line();
и в этой функции она бы сдвигала указатель , то после возврата указатель не был сдвинут?

Когда я использую new то мне обезательно надо освободить занятое место явно?
velgames
 Аватар для velgames
3 / 3 / 1
Регистрация: 09.06.2010
Сообщений: 50
22.04.2012, 11:30     Указатели на указатель #5
Если я правильно понял, то вы пытаетель сделать что то вроде двухмерного массива. Сделайте вот так:

C
1
2
3
4
5
6
7
8
9
int n =10;
int m = 5;
char** a = new char*[n];
for(int i=0;i<n;i++)
{
    a[i] = new char[m];
}
 
// получается массив размером n x m , далее можно спокойно присваивать значения как в обычном массиве

вот это и есть указатель на массив указателей.
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
22.04.2012, 13:42  [ТС]     Указатели на указатель #6
velgames, спасибо за помошь
у меня просто не работал корекно мой вариант

Добавлено через 32 минуты
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>
 
void print(char** p)
{
    while(*p!=0)
        std::cout << *p++ << '\n'; 
}
 char** inPut()
 {
     char** p = new char*[10];
     *p = new char[256];
     std::cin >> *p++; //после считывания строки ошибка
     *p = new char[256];
     *p = '\0';
     std::cout << *p-1;
     return p;
 }
void main()
{
   char** ps = new char*[10];
   ps = inPut();
   print(ps);
   
}
Помогите разобратся
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
22.04.2012, 16:57     Указатели на указатель #7
Цитата Сообщение от balrak Посмотреть сообщение
Merovingian, Спасибо
а если бы я написал ввод через функцию и она возращала указатель на указатель
и в этой функции она бы сдвигала указатель , то после возврата указатель не был сдвинут?

Вот в этом коде вы возвращаете значение сдвинутого указателя
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
char** inPut()
{
     char** p = new char*[10];
     *p = new char[256];
     std::cin >> *p++; //после считывания строки ошибка
     *p = new char[256];
     *p = '\0';
     //std::cout << *p-1; 
     // ошибка тут: обращение к памяти по значению указателя (оператор *)
     // происходит раньше чем вычитание (оператор -)
     std::cout << *(p-1); // так будет работать
     return p;
}
Вы ведь в функцию не передаете указатель, а создаете новый внутри функции. Если бы вы передали функции указатель, внутри функции с ним поработали, а потом вышли из функции, ничего не возвращая, то указатель сохранил бы свое прежнее значение.
Попробуйте написать такую функцию, она будет принимать 1 аргумент!
Прототип будет выглядеть так:
C++
1
void inPut(char * str)
Она более логична, т.к. выполняет более общие действия. Представьте, что вы составляете документацию к вашей функции и пытаетесь описать что она делает(нас так учили). Это будет тяжело, поверьте мне))
void inPut(char * str) осуществляет ввод строки str - тут описать действия функции совсем не сложно

Цитата Сообщение от balrak Посмотреть сообщение
Когда я использую new то мне обезательно надо освободить занятое место явно?
Обязательно.

Цитата Сообщение от Toshkarik Посмотреть сообщение
Merovingian, тык. Но это скорей всего зависит от компилятора. Так что в случае ТС - ему просто повезло.
Согласен. Но я считаю, что лучше писать явно условие. Читабельно + не попадешь впросак как ТС))
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
22.04.2012, 17:07     Указатели на указатель #8
Цитата Сообщение от Merovingian Посмотреть сообщение
Но я считаю, что лучше писать явно условие.
Какое условие Лучше явно обнулять указатели, но не как показали Вы, для этого не нужно создавать статический массив, который будет занимать лишнюю память, особенно если размер массива куда более 10.
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
22.04.2012, 17:17     Указатели на указатель #9
Цитата Сообщение от Toshkarik Посмотреть сообщение
Какое условие Лучше явно обнулять указатели, но не как показали Вы, для этого не нужно создавать статический массив, который будет занимать лишнюю память, особенно если размер массива куда более 10.
Да, кстати, я это и имел ввиду)) просто...

Не по теме:

...просто написал не то, что имел ввиду и подумал, что вы телепат, экстрасенс, колдун, супермен, человек-паук и поймёте меня

balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
22.04.2012, 23:12  [ТС]     Указатели на указатель #10
Toshkarik, разве это обнулит указатель на указатель?
C++
1
char* s[10] = {0};
а как скинуть указатель p то бы он указывал на первое слово?
C++
1
2
3
4
5
6
7
8
9
10
11
 char** inPut()
 {
     char** p = new char*[10];
     *p = new char[256];
     std::cin >> *p++; 
     *p = new char[256];
     std::cin >> *p++;
     *p = new char[256];
     *p = '\0';
     return p;
 }
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
22.04.2012, 23:36     Указатели на указатель #11
C++
1
2
3
4
5
6
7
8
char **p = new char*[ 10 ];
for ( int i = 0; i < 10; i++ ) {
   p[ i ] = new char[ 256 ];
   std::cin >> p[ i ];
}
 
for ( int i = 0; i < 10; i++ )
   std::cout << p[ i ] << std::endl;
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
22.04.2012, 23:56     Указатели на указатель #12
Цитата Сообщение от balrak Посмотреть сообщение
а как скинуть указатель p то бы он указывал на первое слово?
Так, например:
C++
1
2
3
4
5
6
7
8
9
10
11
char** inPut()
{
    char** p = new char*[10];
    char** start = p; // тут запоминаем начало, а дальше делаем все что угодно
    *p = new char[256];
    std::cin >> *p++;
    *p = new char[256];
    *p = '\0';
    std::cout << *(p-1);
    return start; // здесь возвращаем указатель на начало и скидывать ничего не надо
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.04.2012, 19:47     Указатели на указатель
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
23.04.2012, 19:47  [ТС]     Указатели на указатель #13
Merovingian, огромное спасибо
Yandex
Объявления
23.04.2012, 19:47     Указатели на указатель
Ответ Создать тему
Опции темы

Текущее время: 13:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru