Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
aleksand
21 / 9 / 0
Регистрация: 18.06.2011
Сообщений: 185
1

Указатели в массиве

25.09.2012, 10:44. Просмотров 520. Ответов 19
Метки нет (Все метки)

В книжке нет описания к данному коду и мне немного не понятно в некоторых моментах: 1). while (*p) { (не понятно какое условие понимается под *p) 2). while(*p!=' ' && *p) { (*p!= ' ' - это понятно, что если будет пробел, а вот && *p - это что за условие?)
Ответьте пожалуйста на мои вопросы и напишите краткое описание того, как работает программа, у меня в голове немного не укладывается что заем и почему.

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 <cstdio>
using namespace std;
 
int main()
{
    char str[80];
    char token[80];
    char *p, *q;
 
    cout << "Enter any message: \n";
    gets(str);
 
    p = str;
 
    while (*p) {
        q = token;
 
        while(*p!=' ' && *p) {
            *q = *p;
            q++; p++;
        }
        if(*p) p++;
        *q = '\0';
        cout << token << '\n';
    }
 
    system("pause");
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.09.2012, 10:44
Ответы с готовыми решениями:

Указатели на объекты в массиве
#include &lt;iostream&gt; #include &lt;string&gt; using namespace std;...

Указатели в строчном массиве
Помогите, пожалуйста с лабораторной. Ну никак мне эти указатели не влазят в...

Указатели в двумерном массиве
Например есть массив int** mas=new int*; for(int i=0; i&lt;=str;i++) ...

Указатели в двумерном массиве
Помогите пожайлуста!!! Как занулить главную диогональ, скока не пробовал, ни...

Указатели в массиве на сортировку
Доброго,времени,прошу помочь переделать данный код под указатели. ...

19
Nixy
ComfyMobile
400 / 281 / 34
Регистрация: 24.07.2012
Сообщений: 916
25.09.2012, 10:46 2
указывать на 0, в С++ 0 тождественно равен False
но p у тебя указывает на тип char и там
C++
1
'\0'
эквивалент 0
фактически проверяется конец строки
и программа выводит по отдельности разделенные пробелом символьные массивы("слова") до конца строки
1
aleksand
21 / 9 / 0
Регистрация: 18.06.2011
Сообщений: 185
25.09.2012, 10:49  [ТС] 3
Цитата Сообщение от Nixy Посмотреть сообщение
указывать на 0, в С++ 0 тождественно равен False
Вы имеете ввиду первый вопрос как я понял. Т.е. конструкция типа while(*p) { - проверяет нет ли конца строки, т.е. знака \0 в конце, если есть то прекратить?
0
John Prick
836 / 767 / 258
Регистрация: 27.07.2012
Сообщений: 2,179
Завершенные тесты: 3
25.09.2012, 10:50 4
Цитата Сообщение от aleksand Посмотреть сообщение
1). while (*p) { (не понятно какое условие понимается под *p)
*p - разыменовывание указателя p. Разыменовывая указатель, мы получаем значение той переменной, на которую он указывает. Отсюда while (*p) будет работать (в цикл будет заходить), пока то, на что указывает p будет отличным от нуля.

Цитата Сообщение от aleksand Посмотреть сообщение
2). while(*p!=' ' && *p) { (*p!= ' ' - это понятно, что если будет пробел, а вот && *p - это что за условие?)
*p - опять же, то же самое, что и выше. Условие: то, на что указывает p, не равно пробелу и отлично от нуля.

Здесь работа со строкой. Строки в С должны заканчиваться символом 0. Вот на него проверка и делается. Возможно, будет понятнее, если условия с *p заменить на (*p != '\0').
1
Fooly
21 / 17 / 4
Регистрация: 26.03.2012
Сообщений: 147
25.09.2012, 10:52 5
судя по всему p - это адрес, на который указывает указатель. Таким образом while (*р) означает "пока есть какое-то введенное значение str". Хотя я сам ничего теперь не понимаю =) Зачем пишется while(*p!=' ' && *p), если достаточно while(*p!=' ') на мой взгляд, ведь этот цикл уже вложен в первый цикл, в котором второе условие уже проверено while (*р). И что означает q = token; интересно, если q ничего не присвоено, то что присваивается token? Возможно это только часть программы в примере книжки? =) Либо я тугодум =D
0
Andsteadur
153 / 137 / 34
Регистрация: 23.05.2009
Сообщений: 275
25.09.2012, 10:54 6
*p - разыменовываем указатель, получаем значение.
В условных операторах любое значение отличное от нуля дает true.

Добавлено через 1 минуту
while(*p!=' ' && *p) выполняется внутри цикла while (*р). Так что во избежание проблем по достижению конца строки тут тоже нужно проверять на нуль символ
0
Fooly
21 / 17 / 4
Регистрация: 26.03.2012
Сообщений: 147
25.09.2012, 10:56 7
Цитата Сообщение от Andsteadur Посмотреть сообщение
while(*p!=' ' && *p) выполняется внутри цикла while (*р). Так что во избежание проблем по достижению конца строки тут тоже нужно проверять на нуль символ
А поясните плз почему так надо? Разве первым циклом не проверится достижение нуль символа? Если достигнет конца строки то оно и не даст пройтись вложенному циклу.
0
Andsteadur
153 / 137 / 34
Регистрация: 23.05.2009
Сообщений: 275
25.09.2012, 10:58 8
Простой пример:
C++
1
2
3
4
5
6
7
8
9
10
 // p = {'s', 't', 'r', '\0'};
        while (*p) {//*p = 's' => true
 
//если проверять только *p!=' ' , то мы пройдем нуль символ, залезем в память, 
//которая непонятно чем заполнена
        while(*p!=' ' && *p) { 
             p++;
        }
        if(*p) p++;
    }
т.е. это условие нужно для последнего слова в строке, которое заканчивается не пробелом, а символом конца строки.
2
Fooly
21 / 17 / 4
Регистрация: 26.03.2012
Сообщений: 147
25.09.2012, 11:05 9
Цитата Сообщение от Andsteadur Посмотреть сообщение
Простой пример:
C++
1
2
3
4
5
6
7
8
9
10
 // p = {'s', 't', 'r', '\n'};
        while (*p) {//*p = 's' => true
 
//если проверять только *p!=' ' , то мы пройдем нуль символ, залезем в память, 
//которая непонятно чем заполнена
        while(*p!=' ' && *p) { 
             p++;
        }
        if(*p) p++;
    }
т.е. это условие нужно для последнего слова в строке, которое заканчивается не пробелом, а символом конца строки.
непонятно ничего=(
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
while (*p) { //мы проверяем здесь, и входим в цикл, если *p не является /0
        q = token;
 
        while(*p!=' ' && *p) { //т.к мы уже проверили и знаем, что *p не является концом строки, 
                                      // то достаточно проверить не является ли *р пробелом. 
                                      // Зачем проверять второй раз, если мы уже знаем, что *р - не конец строки???
            *q = *p;
            q++; p++;
        }
        if(*p) p++;
        *q = '\0';
        cout << token << '\n';
    }
0
aleksand
21 / 9 / 0
Регистрация: 18.06.2011
Сообщений: 185
25.09.2012, 11:05  [ТС] 10
Теперь стало ясно как работает программа. Всем спасибо, вопрос исчерпан.
0
Nixy
ComfyMobile
400 / 281 / 34
Регистрация: 24.07.2012
Сообщений: 916
25.09.2012, 11:08 11
Fooly, если ты уберешь это условие то
C++
1
2
3
4
while(*p!=' ') {
            *q = *p;
            q++; p++;
        }
будет работать вечно так как в конце последнего слова p указывает не на ' ' а на '\0' они не равны
1
Fooly
21 / 17 / 4
Регистрация: 26.03.2012
Сообщений: 147
25.09.2012, 11:15 12
Цитата Сообщение от aleksand Посмотреть сообщение
Теперь стало ясно как работает программа. Всем спасибо, вопрос исчерпан.
Мне вообще ничего не понятно теперь Поясните мне всё
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while (*p) { //мы проверяем здесь, и входим в цикл, если *p не является /0
        q = token;
 
        while(*p!=' ' && *p) { //т.к мы уже проверили и знаем, что *p не является концом строки, 
                                      // то достаточно проверить не является ли *р пробелом. 
                                      // Зачем проверять второй раз, если мы уже знаем, что *р -                                    
                                     //  не конец строки???
            *q = *p;
            q++; p++;
        }
        if(*p) p++; //Опять 25. Зачем тут if объясните?
        *q = '\0';   // ???
        cout << token << '\n'; // и что нам тут выведет? ничего же ведь не выведет? а когда 
                                       // тут что-нибудь выводиться будет? никогда же, зачем тогда писать?
    }
0
Nixy
ComfyMobile
400 / 281 / 34
Регистрация: 24.07.2012
Сообщений: 916
25.09.2012, 11:17 13
Fooly, я же вверху ответил посмотри внимательно
C++
1
if(*p) p++; //Опять 25. Зачем тут if объясните?
операция p++ увеличивает адрес на величину типа ,на который указывает , то есть происходит смещение в право и мы движемся по строке , как я писал в теме '\0' конец строки эквивалент 0 и false соответственно , дальше конца строки двигатся мы не должны , это будет считатся выходом за пределы символьного массива
1
Fooly
21 / 17 / 4
Регистрация: 26.03.2012
Сообщений: 147
25.09.2012, 11:18 14
Цитата Сообщение от Nixy Посмотреть сообщение
Fooly, если ты уберешь это условие то
C++
1
2
3
4
while(*p!=' ') {
            *q = *p;
            q++; p++;
        }
будет работать вечно так как в конце последнего слова p указывает не на ' ' а на '\0' они не равны
Т.е сразу первый цикл проверяет не по одному символу, а сразу загружает весь массив? Если так, то понятно. А я думал по одному символу проверяет из массива. Или я опять неправильно понял?

ЗЫ
оно же по одному всё-таки символу проверяет начиная с нулевого. Тогда почему не написать

C++
1
2
3
4
if(*p!=' ') {
            *q = *p;
            q++; p++;
        }
и почему этот цикл не будет также бесконечным?
C++
1
2
3
4
   while(*p!=' ' && *p) {
            *q = *p;
            q++; p++;
        }
У меня сейчас опять взорвётся мозг, т.к у меня ничего не может уложиться в голове =) Видать я с этими указателями дуб дубом, но сколько не читал, вс равно с ними постоянно проблемы =(
0
Nixy
ComfyMobile
400 / 281 / 34
Регистрация: 24.07.2012
Сообщений: 916
25.09.2012, 11:27 15
первое условие проверяет конец всей строки , второе проверяет конец строки + конец отрезка строки "слова" разделеного пробелом ' ' для того чтобы обновить q
C++
1
2
3
4
5
6
7
8
9
10
11
while (*p) { //мы проверяем здесь, и входим в цикл, если *p не является /0
        q = token; // тут q указывает на массив символов token а точнее на все что в ней записано до первого '\0' и так далее
 
        while(*p!=' ' && *p) {
            *q = *p; // тут в q записывается содержимое p
            q++; p++;
        }
        if(*p) p++; //Объяснил чуть выше
        *q = '\0';   // переход на следующую строку в массиве token
        cout << token << '\n'; // а выводить будет то что было записано в q
    }
Добавлено через 1 минуту
Fooly, есть такая клевая штука дебаг режим , пока твой мозг не стал компилятором кода используй его и проверяй все что происходит, в будующем если ты будешь усложнять код и не понимать что там происходит , будешь разбивать его на части , и также дебагом пробегать , пока твой мозг не станет компилятором
1
Fooly
21 / 17 / 4
Регистрация: 26.03.2012
Сообщений: 147
25.09.2012, 11:36 16
Так, я практически всё понял кроме одного... так сказать
Допустим у нас записан массив "stasik mihajlov/0"
Первый цикл
C++
1
while (*p)
проверяет по одному символу, праивльно? Т.е сначала буковку "s", потом "t" итд.
Когда же доходим до "/0", то мы не входим даже в цикл. И вообще цикл закончится на этом. Правильно? =)
Так вот... Хоть убейте, но я не понимаю зачем нам проверять
C++
1
while(*p!=' ' && *p)
если мы знаем, что *p не может быть равным /0
И более того, я не понимаю зачем тут цикл while, если правильнее (на мой взгляд) будет иф
C++
1
2
3
4
if(*p!=' ') {
            *q = *p;
            q++; p++;
        }
и Опять
C++
1
if(*p) p++;
я понял что мне написали выше, но я не пойму зачем он тут, если опять-таки *p никак не может быть тут равен /0 , т.к мы не войдём даже в вышестоящий цикл while.
Извиняюсь, что я туплю, но я хочу полностью понять это ситуацию, чтобы больше не возникало вопросов =)

PS сейчас всё прокомпилирую, и если разберусь, то сниму все вопросы, а пока убирать свои дотошные вопросики убирать отсюда не буду
0
Nixy
ComfyMobile
400 / 281 / 34
Регистрация: 24.07.2012
Сообщений: 916
25.09.2012, 11:48 17
Цитата Сообщение от Fooly Посмотреть сообщение
никак не может быть тут равен /0
не верно посмотри внимательно где у тебя инкримент p он какраз внутри цикла
C++
1
2
3
4
 while(*p!=' ' && *p) {// если слово было последним у него в конце стоит   '/0'     а не ' '                               
            *q = *p;
            q++; p++;// тут мы сдвигаемся в право и если конец и убрать условие будем делать это вечно ну либо пока в муссоре не попадется нам ' '
        }
C++
1
if(*p) p++;// чтоб не уйти дальше конца строки иначе мы сдвинемся дальше в муссор там не '/0' и внешний цикл продолжит работу
1
Fooly
21 / 17 / 4
Регистрация: 26.03.2012
Сообщений: 147
25.09.2012, 11:55 18
Что загружает
C++
1
while (*p)
1 символ (как я думаю, но мне уже кажется, что так не может быть) или сразу всё слово до пробела? Если всё слово, то всё понятно в коде. ТОлько теперь я не понимаю, почему оно загружает слово сразу, а не по символам?
0
Andsteadur
153 / 137 / 34
Регистрация: 23.05.2009
Сообщений: 275
25.09.2012, 12:51 19
C++
1
while (*p)
цикл выполняется пока символ, который хранится по адресу p не является нуль символом. Дальше в цикле мы изменяем указатель (++p) и он начинает указывать на другой участок паяти, который хранит другой символ.

Добавлено через 9 минут
Т.е. если p = {'a', 'b', '\0'}, то *p указывает на 'a'
C++
1
2
3
4
5
6
while (*p) {
         while(*p!=' ' && *p) {
                  p++;
        }
        if(*p) p++;
}
Bот так будет выполняться участок кода для p = {'a', 'b', '\0'};

1. Строка 1: разыменовываем указатель *p = 'a', значение отличное от нуля поэтому выполняем итерацию цикла
2. Строка 2: *p != ' ' и *p != 0 (т.к. *p='a'). Выполняем итерацию вложенного цикла
3. Строка 3: смещаем указатель p. p теперь указывает на 'b'
4. Строка 4: конец итерации вложенного цикла
5. Строка 2: *p != ' ' и *p != 0 (т.к. *p='b'). Выполняем итерацию вложенного цикла
6. Строка 3: смещаем указатель p. p теперь указывает на '\0'
7. Строка 2: *p != ' ' и *p == 0 (т.к. *p='\0'). Закончить выполнение вложенного цикла
8. Строка 5: *p == 0 (т.к. *p='\0'). Не входим в true-блок.
9. Строка 6: конец итерации главного цикла.
10. Строка 1: *p == 0 (т.к. *p='\0'). Закончить выполнение главного цикла
2
taras atavin
4204 / 1767 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.09.2012, 13:11 20
Цитата Сообщение от aleksand Посмотреть сообщение
не понятно какое условие понимается под *p
указывает на не нулевой символ. Что здесь сложного?
0
25.09.2012, 13:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.09.2012, 13:11

Найти сумму положительных элементов в массиве через указатели
Найти сумму положительных элементов в массиве через указатели. Ввод массива...

Изменить порядок следования элементов в массиве используя указатели
Вот что есть, почему не работает правильно не понимаю, подскажите плиз) #...

Проверить, чередуются ли в массиве четные и нечетные числа (указатели)
Дан массив ненулевых целых чисел размера N. Проверить, чередуются ли в нем...


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

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

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