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

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

Войти
Регистрация
Восстановить пароль
 
 
aleksand
21 / 9 / 2
Регистрация: 18.06.2011
Сообщений: 185
#1

Указатели в массиве - C++

25.09.2012, 10:44. Просмотров 485. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Указатели в массиве (C++):

Указатели в строчном массиве - C++
Помогите, пожалуйста с лабораторной. Ну никак мне эти указатели не влазят в голову :( , может с вашей подсказкой на примере своей...

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

Указатели в двумерном массиве - C++
Помогите пожайлуста!!! Как занулить главную диогональ, скока не пробовал, ни как не получается.... не могу найти ошибку :wall: Вот...

Указатели в массиве на сортировку - C++
Доброго,времени,прошу помочь переделать данный код под указатели. #include &lt;iostream&gt; #include &lt;ctime&gt; #include...

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

Изменить порядок следования элементов в массиве используя указатели - C++
Вот что есть, почему не работает правильно не понимаю, подскажите плиз) # include &lt;iostream&gt; using namespace std; //7.Пользуясь ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 24.07.2012
Сообщений: 916
25.09.2012, 10:46 #2
указывать на 0, в С++ 0 тождественно равен False
но p у тебя указывает на тип char и там
C++
1
'\0'
эквивалент 0
фактически проверяется конец строки
и программа выводит по отдельности разделенные пробелом символьные массивы("слова") до конца строки
1
aleksand
21 / 9 / 2
Регистрация: 18.06.2011
Сообщений: 185
25.09.2012, 10:49  [ТС] #3
Цитата Сообщение от Nixy Посмотреть сообщение
указывать на 0, в С++ 0 тождественно равен False
Вы имеете ввиду первый вопрос как я понял. Т.е. конструкция типа while(*p) { - проверяет нет ли конца строки, т.е. знака \0 в конце, если есть то прекратить?
0
John Prick
801 / 734 / 145
Регистрация: 27.07.2012
Сообщений: 2,107
Завершенные тесты: 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 / 1
Регистрация: 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 / 3
Регистрация: 23.05.2009
Сообщений: 275
25.09.2012, 10:54 #6
*p - разыменовываем указатель, получаем значение.
В условных операторах любое значение отличное от нуля дает true.

Добавлено через 1 минуту
while(*p!=' ' && *p) выполняется внутри цикла while (*р). Так что во избежание проблем по достижению конца строки тут тоже нужно проверять на нуль символ
0
Fooly
21 / 17 / 1
Регистрация: 26.03.2012
Сообщений: 147
25.09.2012, 10:56 #7
Цитата Сообщение от Andsteadur Посмотреть сообщение
while(*p!=' ' && *p) выполняется внутри цикла while (*р). Так что во избежание проблем по достижению конца строки тут тоже нужно проверять на нуль символ
А поясните плз почему так надо? Разве первым циклом не проверится достижение нуль символа? Если достигнет конца строки то оно и не даст пройтись вложенному циклу.
0
Andsteadur
153 / 137 / 3
Регистрация: 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 / 1
Регистрация: 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 / 2
Регистрация: 18.06.2011
Сообщений: 185
25.09.2012, 11:05  [ТС] #10
Теперь стало ясно как работает программа. Всем спасибо, вопрос исчерпан.
0
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 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 / 1
Регистрация: 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 / 8
Регистрация: 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 / 1
Регистрация: 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 / 8
Регистрация: 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.09.2012, 11:27
Привет! Вот еще темы с ответами:

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

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

Указатели: определить число отрицательных элементов в массиве и вывести их адреса - C++
Привет всем, я хотел бы узнать как решается данная задачка: Написать программу, определяющую число отрицательных элементов в массиве и...

Работа с массивом через указатели(Определить, строго ли чередуются элементы в массиве) - C++
Задан массив из N элементов, состоящий только из нулей и единиц. Определить, строго ли чередуются элементы в массиве. Программа должна...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
25.09.2012, 11:27
Ответ Создать тему
Опции темы

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