Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика_и_Пр_Бизнес_лекции.doc
Скачиваний:
90
Добавлен:
10.05.2015
Размер:
1.21 Mб
Скачать

6.3. Связь между указателями и массивами

Указатели и массивы в языке С++ взаимосвязаны и могут использоваться в программе почти одинаково. В языке С++ имя массива является константным указателем, содержащим адрес начала массива (адрес 0-элемента). Изменить значение константного указателя нельзя, поэтому нельзя присвоить один массив другому. Но так как массив является указателем, то к нему можно применять некоторые операции, определенные для указателей. Например, можно обращаться к элементам массива с помощью смещения указателя относительно начала массива:

int a[5]={10, 20, 30, 40, 50};

*a=1; //равносильно a[0]=1;

*(a+1)=2; //равносильно a[1]=2;

Для С++ справедливо утверждение: указатель, содержащий адрес начала массива (или адрес любого элемента массива), можно рассматривать как массив, который находится по адресу, хранящемуся в указателе. Следовательно, указатель, который указывает на элемент массива, можно индексировать.

Пример использования указателя и массива:

char s[10]=”abcdef”; //массив символов

char *ps; //указатель на символ

ps=s; //указатель содержит адрес массива символов s

cout<<s<<endl; //abcdef

cout<<ps;<<endl; //abcdef

ps=&s[2]; // указатель содержит адрес элемента массива символов

cout<<ps;<<endl; //cdef (вывод части строки)

ps[0]=’#’; //изменение содержимого строки через указатель

cout<<ps;<<endl; //#def (вывод части строки)

cout<<s;<<endl; //ab#def (вывод измененной строки)

6.4. Функция strtok для выделения лексем из текста

Слова текста можно рассматривать как неделимые объекты – лексемы, а знаки пунктуации – как разделители лексем. Можно лексемой считать предложение, а разделителями лексем-предложений считать точку, восклицательный и вопросительный знаки.

Функция strtok из стандартной библиотеки string используется для выделения лексем из строки. У функции есть два аргумента. При первом вызове первый аргумент – строка, из которой надо выделить первую лексему, а второй – строка разделителей лексем. Результат функции – адрес первой лексемы. Например, для выделения первого слова в тексте, в котором слова разделены пробелами и запятыми, можно использовать код:

char s[81]=”abc fgh, aa”;

char *p;

p=strtok(s,” ,“);

cout<<p<<endl; // abc

Функция находит первый символ ('a'), отличный от разделителя – адрес этого символа и есть адрес первой лексемы. Кроме того, функция находит первый разделитель в строке (' ') и заменяет его 0-символом. Теперь можно вывести строку, заданную указателем р или выполнить с ней другие действия. Функция также находит в строке и сохраняет в своих внутренних переменных адрес следующей лексемы (или 0, если в строке больше нет лексем). Для выделения из строки следующей лексемы функция вызывается повторно, но в качестве первого аргумента функции указывается значение 0. Например,

p=strtok(0,” ,“);

cout<<p<<endl; //fgh

Функция strtok, выделяя из строки лексемы, изменяет строку. Поэтому, если со строкой надо работать далее, ее надо предварительно сохранить в другой переменной.

Пример программы, которая находит количество вхождений заданного слова в текст, слова в котором разделены знаками пунктуации и пробелами:

#include <conio.h>

#include <iostream.h>

#include <string.h>

void main()

{

char r[]=" ,.!?:;-"; //массив разделителей

char s[81]; //текст

char word[21]; //слово-образец

char *pw; //адрес очередного слова (лексемы)

int k; //счетчик вхождений слова word в текст

cout<<”s? “;

cin.getline(s,81); //чтение строки с пробелами

cout<<”word? “;

cin>>word;

k=0;

pw=strtok(s,r); //выделение первого слова

while(pw!=0) //цикл выделения и сравнения слов-лексем

{

if (strcmp(pw,word)==0)

k++;

pw=strtok(0,r); //выделение следующего слова

}

cout<<”k=”<<k;

getch();

}