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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
#1

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

22.04.2012, 04:17. Просмотров 2029. Ответов 12
Метки нет (Все метки)

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)
не прирывает функцию?
Почему не выводится первый элемент?
Спаибо за помошь )
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.04.2012, 04:17
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатели на указатель (C++):

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

Сортировка через ссылку на (указатель на указатели) - C++
Нужно, что бы функция принимала ссылку на указатель на много указателей,( и количество указателей, ясен пень.) И сортировала все ето,...

Константный указатель на константные данные (указатели) - C++
В общем если раскомментить const то ничего не работает может кто знает как правильно передавать константный указатель на константные...

Указатели и ссылки. Имя массива как указатель - C++
7. Дан одномерный массив, состоящий из N целочисленных элементов. 7.1. Ввести массив с клавиатуры. 7.2. Найти минимальный положительный...

Указатели( с элементами массива надо работать через указатель, а не индекс) - C++
Заданы осадки по месяцам, зафиксированные метеостанцией в течение прошедшего года. Занесите эти данные в массив и определите минимальное,...

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

12
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
}
1
Toshkarik
1143 / 860 / 51
Регистрация: 03.08.2011
Сообщений: 2,390
Завершенные тесты: 1
22.04.2012, 09:08 #3
Merovingian, тык. Но это скорей всего зависит от компилятора. Так что в случае ТС - ему просто повезло.
0
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
22.04.2012, 11:23  [ТС] #4
Merovingian, Спасибо
а если бы я написал ввод через функцию и она возращала указатель на указатель
C++
1
char** new_line();
и в этой функции она бы сдвигала указатель , то после возврата указатель не был сдвинут?

Когда я использую new то мне обезательно надо освободить занятое место явно?
0
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 , далее можно спокойно присваивать значения как в обычном массиве

вот это и есть указатель на массив указателей.
0
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);
   
}
Помогите разобратся
0
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, тык. Но это скорей всего зависит от компилятора. Так что в случае ТС - ему просто повезло.
Согласен. Но я считаю, что лучше писать явно условие. Читабельно + не попадешь впросак как ТС))
0
Toshkarik
1143 / 860 / 51
Регистрация: 03.08.2011
Сообщений: 2,390
Завершенные тесты: 1
22.04.2012, 17:07 #8
Цитата Сообщение от Merovingian Посмотреть сообщение
Но я считаю, что лучше писать явно условие.
Какое условие Лучше явно обнулять указатели, но не как показали Вы, для этого не нужно создавать статический массив, который будет занимать лишнюю память, особенно если размер массива куда более 10.
1
Merovingian
54 / 54 / 5
Регистрация: 24.09.2011
Сообщений: 149
22.04.2012, 17:17 #9
Цитата Сообщение от Toshkarik Посмотреть сообщение
Какое условие Лучше явно обнулять указатели, но не как показали Вы, для этого не нужно создавать статический массив, который будет занимать лишнюю память, особенно если размер массива куда более 10.
Да, кстати, я это и имел ввиду)) просто...

Не по теме:

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

0
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;
 }
0
Toshkarik
1143 / 860 / 51
Регистрация: 03.08.2011
Сообщений: 2,390
Завершенные тесты: 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;
0
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; // здесь возвращаем указатель на начало и скидывать ничего не надо
}
1
balrak
6 / 6 / 1
Регистрация: 01.04.2012
Сообщений: 81
23.04.2012, 19:47  [ТС] #13
Merovingian, огромное спасибо
0
23.04.2012, 19:47
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.04.2012, 19:47
Привет! Вот еще темы с ответами:

Указатели и указатели на указатели, а также типы данных - C++
Недавно начал изучать Си, перешел с Delphi. Много непонятного и пока процесс идет медленно. Накачал литературы, буду изучать) Щас...

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

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

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


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

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

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