/* Считываем символы до тех пор, пока не встретится либо пробел, либо нулевой символ (признак завершения строки). */

  while(*p != ' ' && *р) {

   *q = *р;

   q++; р++;

  }

  if(*p) р++; // Перемещаемся за пробел.

  *q = '\0'; // Завершаем лексему нулевым символом.

  cout << token << '\n';

 }

 return 0;

}

А вот как выглядит версия той же программы с использованием индексирования массивов.

// Программа разбиения строки на слова:

// версия с использованием индексирования массивов.

#include

#include

using namespace std;

int main()

{

 char str[80];

 char token[80];

 int i, j;

 cout << "Введите предложение: ";

 gets(str);

 // Считываем лексему из строки.

 for(i=0; ; i++) {

  /* Считываем символы до тех пор пока не встретится либо пробел, либо нулевой символ (признак завершения строки). */

  for(j=0; str[i]!=' ' && str[i]; j++, i++)

   token[j] = str[i];

  token[j] = '\0'; // Завершаем лексему нулевым символом.

  cout << token << '\n';

  if(!str[i]) break;

 }

 return 0;

}

У этих программ может быть различное быстродействие, что обусловлено особенностями генерирования кода С++-компиляторами. Как правило, при использовании индексирования массивов генерируется более длинный код (с большим количеством машинных команд), чем при выполнении арифметических действий над указателями. Поэтому неудивительно, что в профессионально написанном С++-коде чаще встречаются версии, ориентированные на обработку указателей. Но если вы— начинающий программист, смело используйте индексирование массивов, пока не научитесь свободно обращаться с указателями.

Индексирование указателя

Как было показано выше, можно получить доступ к массиву, используя арифметические действия над указателями. Интересно то, что в C++ указатель, Который ссылается на массив, можно индексировать так, как если бы это было имя массива (это говорит о тесной связи между указателями и массивами). Соответствующий такому подходу синтаксис обеспечивает альтернативу арифметическим операциям над указателями, поскольку он более удобен в некоторых ситуациях. Рассмотрим пример.

// Индексирование указателя подобно массиву.

#include

#include

using namespace std;

int main()

{

 char str[20] = "I love you";

 char *p;

 int i;

 p = str;

 // Индексируем указатель.

 for(i=0; p[i]; i++) p[i] = toupper(p[i]);

 cout << p; // Отображаем строку.

 return 0;

}

При выполнении программа отобразит на экране следующее.

I LOVE YOU

Вот как работает эта программа. Сначала в массив str вводится строка "I love you". Затем адрес начала этой строки присваивается указателю р. После этого каждый символ строки str с помощью функции toupper() преобразуется в его прописной эквивалент посредством индексирования указателя р. Помните, что выражение р[i] по своему действию идентично выражению *(p+i).

О взаимозаменяемости указателей и массивов

Выше было показано, что указатели и массивы очень тесно связаны. И действительно, во многих случаях они взаимозаменяемы. Например, с помощью указателя, который содержит адрес начала массива, можно получить доступ к элементам этого массива либо посредством арифметических действий над указателем, либо посредством индексирования массива. Однако в общем случае указатели и массивы не являются взаимозаменяемыми. Рассмотрим, например, такой фрагмент кода.

int num[10];

int i;

for(i=0; i<10; i++) {

 *num = i; // Здесь все в порядке.

 num++; // ОШИБКА — переменную num модифицировать нельзя.

}

Перейти на страницу:

Все книги серии Изучайте C++ с профессионалами

Похожие книги