Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
15 / 15 / 2
Регистрация: 26.04.2012
Сообщений: 1,091
1

По. разобрать программу с указателями и массивами ( авторы Либерти, Дмитрий )

25.09.2013, 14:22. Показов 1327. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Программа

В строках 26, 28 мы создаем массивы?

С помощю getline мы вводим строку. И о чудо! я вижу, что теперь в массиве не 225 символов, а столько, сколько
я вводил.

bool GetWord(char* string, char* word, int& wordOffset) указатели на массив? int& нну забыл, и не сображу, это что?

cout << "string[wordOffset]: " << string[wordOffset] << endl; ( стр.63 ) выводит 284 символа, причем сначала 4 строки бог знает каких символов и тут же без перехода введённую строку.

char *p1, *p2; (стр.71) самая непонятка!!!!! Это же указатель. Вот мы ег обьявили

p1 = p2 = string+wordOffset; Что же в нем хранится? Указатель? почему при прямом выводе выводится не адрес, а строка? Я ожидал, что так буде вывиден cout << "p1: " << p1 << endl;адрес, а так cout << "*p1: " <<*p1 << endl;
строка, однако строка выводится прямо!!

Мало того, при операции p1++; из строки сначала вычитается по символу на каждый шаг!! Как это???? Офигеть!!

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//Листинг 8.11. Выделение слов из массива символов
#include <string> 
#include <iostream> // для объекта cout
using namespace std;
 
#include<iomanip>
//Этот файл содержит большую часть манипуляторов C++. Если вы не знаете, что такое манипулятор, не беспокойтесь. Просто подключите это файл вместе с iostream, хуже не станет.
#include<fstream> 
//Подключается при работе с файлами.
 
 
 #include <ctype.h>
 
 #include <string.h>
 
 bool GetWord(char* string, char* word, int& wordOffset);
 
 // основная программа
 
 int main()
 
 {   char*  sprobuem;
 
     const int bufferSize = 255;
 
     char buffer[bufferSize+1]; // переменная для хранения всей строки
 
     char word[bufferSize+1]; // переменная для хранения слова
 
     int wordOffset = 0; // начинаем с первого символа
 
     cout << "Enter а string: ";  
 
     cin.getline(buffer,bufferSize);
 
     sprobuem=buffer; cout << "sprobuem: " << sprobuem << endl;
 
     
 
  while (GetWord(buffer,word,wordOffset))
 
   {
    cout << "Got this word: " << word << endl;
   }
 
 
 
  system("pause  ");return(0);
 
 }
 
 
 
 // Функция для выделения слова из строки символов.
 
 bool GetWord(char* string, char* word, int& wordOffset)
 
 {
 
     cout << "string: " << string << endl;
     cout << "word: " << word << endl;
     cout << "wordOffset: " << wordOffset << endl;
     cout << "string[wordOffset]: " << string[wordOffset] << endl;
 
    if (!string[wordOffset]) // определяет конец строки?
 
      return false;
 
 
 
    char *p1, *p2;
 
    p1 = p2 = string+wordOffset; // указатель на следующее слово
     cout << "p1: " << p1 << endl;
       cout << "p2: " << p2 << endl;
 
 
 
    // удаляем ведущие пробелы
       cout << "strlen(p1): " << strlen(p1) << endl;  cout << "isalnum(p1[0]): " << isalnum(p1[0]) << endl;
 
    for (int i = 0; i<(int)strlen(p1) && !isalnum(p1[0]); i++){// strlen Возвращает длину строки с завершающим нулевым символом
 
      p1++; //Функция isalnum() возвращает ненулевое значение, если ее аргумент ch является либо буквой, либо цифрой. 
      cout << "p1: " << p1 << endl; cout << "i: " << i << endl;}
 
 
    // проверка наличия слова
 
   // if (!iKalruj[n(pl[0]))
 
   //   return false;
 
 
 
    // указатель р1 показание начало сдолующего слова
 
    // iа к жо как и p2
 
    p2 = p1;  
 
 
 
    // перпмещавм p2 и конец олова
 
    while (isalnum(p2[0]))
 
    {   p2++;    cout << "p2++: " << p2 << endl; }
 
 
 
    // p2 указывает на конец слова
 
    // а p1 - в начало
 
    // разность указатолой показываот длину слова
 
    int len = int (p2 - p1);     cout << "len: " << len << endl;   cout << "p2 - p1: " << p2 - p1 << endl; 
 
 
 
    // копируем слово в буфер
 
    strncpy (word,p1,len);  // Функция strncpy() копирует до count символов из строки, адресуемой параметром str2, в массив, адресуемый параметром str1. Параметр str2 должен указывать на строку с завершающим нулевым символом.
 
    cout << "word: " << word << endl;   cout << "strlen(word): " << strlen(word) << endl;
 
 
 
    // и добавляем символ разрыва сроки
 
    word[len]='\0';   for (int i = 0; i<=len; i++) cout << "word[i]: " << word[i] << "    [i]: " << i  <<  endl;
    cout << "word: " << word << endl;
 
 
    // ищем начало следующего слова
 
    for (int i = int(p2-string); i<(int)strlen(string) && !isalnum(p2[0]); i++) // strlen Возвращает длину строки с завершающим нулевым символом
 
      p2++;   //Функция isalnum() возвращает ненулевое значение, если ее аргумент ch является либо буквой, либо цифрой. 
 
 
 
    wordOffset = int(p2-string);
 
 
 
    return true;
 
 }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.09.2013, 14:22
Ответы с готовыми решениями:

Разобрать код с указателями
Если делать так, то приложение крэшится: char *str = &quot;71903asgd5&quot;; *(str+1) = 'd'; ...

Разобрать код, демонстрирующий работу с указателями
Здравствуйте. Помогите пожалуйста разобраться с работой указателей. #include &lt;iostream&gt; using...

Работа с массивами и указателями
I. Пусть v1 = v2 = 0; v3=1.5; vi= i+1/i2+1*vi-1-vi-2*vi-3 i=4,5,6 Дано натуральное n (n&gt;=4)....

Работа с массивами/указателями
я чего-то туплю, задача такая, надо в i строку двумерного массива записать ptr_buffer. Вот код: но...

3
147 / 82 / 10
Регистрация: 04.09.2013
Сообщений: 261
25.09.2013, 16:09 2
С помощю getline мы вводим строку. И о чудо! я вижу, что теперь в массиве не 225 символов, а столько, сколько
я вводил.
- каким образом вы определяете что там меньше 255? Массив как был так и остался на 255 символов, просто getline в конец строки добавляет 0 (символ конца строки) и поэтому отображаются только те символы которые считала функция getline, однако дальнейшие значения в массиве как были так и остались.

bool GetWord(char* string, char* word, int& wordOffset) указатели на массив? int& нну забыл, и не сображу, это что?
тут все просто последний параметр передается ссылкой. Соответственно все изменения значения данной переменной внутри функции отобразятся на передаваемой переменной, по сути сюда и будет возвращаться позиция в строке с которой начинается слово.

Не по теме:

Ох же блин и выводов на экран тут. наверное для дебага



cout << "string[wordOffset]: " << string[wordOffset] << endl; ( стр.63 ) выводит 284 символа, причем сначала 4 строки бог знает каких символов и тут же без перехода введённую строку.
а вы уверенны что именно в этой стоке проблема, т.к. тут выводится только 1 символ а вот
строка выше
cout << "word: " << word << endl;
по началу выведет кто знает что и вообще кажется может вызвать ошибку, т.к. память под word выделяется, а вот значения не инициализируется. А строка как нам известно выводится то символа окончания строки (а именно нуля), чего может не оказаться, т.к. кто его знает что было в той памяти что выделена ранее.

char *p1, *p2; (стр.71) самая непонятка!!!!! Это же указатель. Вот мы ег обьявили

p1 = p2 = string+wordOffset; Что же в нем хранится? Указатель? почему при прямом выводе выводится не адрес, а строка? Я ожидал, что так буде вывиден cout << "p1: " << p1 << endl;адрес, а так cout << "*p1: " <<*p1 << endl;
строка, однако строка выводится прямо!!
ну тут тоже все ясно р1 и р2 указатели но в то же время мы помним, что строки мы так же объявляем через указатели и потому при выводе р1 и р2 выводятся как строки.
опять таки string это ведь тоже указатель и хранит в себе адрес памяти где начинается строка. Соответственно мы знаем, что char занимает 1 байт памяти, поэтому string+wordOffset по сути эквивалентно &string[wordOffset] т.е. адрес смещенный в строке.
По такому-же принципу p1++ производит смещение на 1 символ
1
15 / 15 / 2
Регистрация: 26.04.2012
Сообщений: 1,091
25.09.2013, 18:44  [ТС] 3
Спасибо!!!!!

Добавлено через 1 час 57 минут
Вобще не понял где ошибка.

C++
1
2
3
4
5
6
7
8
9
sprobuem=buffer; cout << "sprobuem: " << sprobuem << endl;
 
     for (int i=0;i<bufferSize+10;i++0)
     {   cout << "sprobuem: " << sprobuem+i << endl;}
 
 
     
 
  while (GetWord(buffer,word,wordOffset))

1>d:\проги\widelenyeslovmassiva\widelenyeslovmassiva\widelenyeslovmassiva.cpp(38 ): error C2143: синтаксическая ошибка: отсутствие ")" перед "константа"
1>d:\проги\widelenyeslovmassiva\widelenyeslovmassiva\widelenyeslovmassiva.cpp(38 ): error C2059: синтаксическая ошибка: )
1>d:\проги\widelenyeslovmassiva\widelenyeslovmassiva\widelenyeslovmassiva.cpp(39 ): error C2143: синтаксическая ошибка: отсутствие ";" перед "{"
1>d:\проги\widelenyeslovmassiva\widelenyeslovmassiva\widelenyeslovmassiva.cpp(39 ): error C2065: i: необъявленный идентификатор
1>d:\проги\widelenyeslovmassiva\widelenyeslovmassiva\widelenyeslovmassiva.cpp(47 ): error C2065: i: необъявленный идентификатор
1> Выход из команды с кодом "2".

Добавлено через 25 минут
Логика вопроса. Мы допустим обьявили переменную как ссылку, но поместили в нее не ссылку на массив, а массив.
Не так sprobuem=&buffer; а так sprobuem=buffer;. Положим, в ней лежит как-бы то ни было массив.

Как мы тогда с ним работаем так p1++; сдвигая пошагово? Или проще не заморачиваться а пытаться использовать, в дальнейшем?
0
147 / 82 / 10
Регистрация: 04.09.2013
Сообщений: 261
26.09.2013, 11:31 4
Цитата Сообщение от Dimka-novitsek Посмотреть сообщение
for (int i=0;i<bufferSize+10;i++0)
я бы сказал там нулик лишний в конце после ++
Смотри
ссылки и указатели это по сути переменные типа лонг, в которых хранится адрес памяти по которому лежат какие-то данные. Соответственно ожидаемый тип данных мы указываем при определении указателя. т.е. char *c означает что в переменной с будет находится адрес памяти по которому мы ожидаем считать значение типа чар.

Таким образом по идее код
Цитата Сообщение от Dimka-novitsek Посмотреть сообщение
sprobuem=&buffer
не должен работать, т.к. у тебя тип данных указатель на чар, а ты передаешь адрес памяти указателя на чар, т.е получаешь указатель на указатель чар.

Логика пока понятна думаю.
Теперь допустим у тебя в коде получается
C++
1
p2 = string;
, таким образом обе переменные хранят в себе один и тот же адрес.Мы помним что по сути указатель это длинное целое, следовательно он поддерживает все стандартные арифметические операторы следовательно если мы сделаем команду p2++, то р2 уже будет хранить адрес на 1 болше чем ранее, следовательно будет уже указывать не на начало строки а на 2 символ в строке, однако если бы переменная стринг являлась бы не строкой а например массивом типа ворд, тогда после выполнения команды р2++ получается, что р2 уже не указывает на начало массива, но еще не указывает на следующий элемент массива, т.к. размер памяти занимаемый типом ворд равен 2 байтам а не одному.

Т.ч. на самом деле лучше арифметические операции с указателями не делать, лучше пользоваться механизмом индексации типизированных указателей.

Ссылки и указатели свою суть хранят в названии они не хранят данные они хранят в себе информацию о том где эти данные брать.
1
26.09.2013, 11:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.09.2013, 11:31
Помогаю со студенческими работами здесь

Связь между указателями и массивами
С помощью указателя написать функцию, которая подсчитывает количество нулевых элементов в массиве...

Работа с указателями/массивами /функциями
Запутался с указателями/в лабе нужно провести через указатели /Дан одномерный массив из К...

Работа с массивами, указателями и функциями.
Я вот рли не знаю, как отправить в свою созданную функцию массив, как потом обработанный массив в...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru