Строки и указатели

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

Так как все строки в языке С++ заканчиваются нулевым символом, который имеет значение <ложь>, то условие в операторе while(*str) будет истинным до тех пор, пока программа не достигнет конца строки.

При работе со строками в большинстве случаев целесообразно применять указатели. Приведем примеры фрагментов программ:

/*Пример копирования строки s2 в s1*/

char *s1, char *s2;

char *ptrs1 = s1;

//указатель инициализирован на начало строки

while ((*s1++ = *s2++)!= 0);

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

/*Пример пользовательской функции конкатенации*/

char *s1, char *s2;

char *p1, *p2;

p1 = s1; p2 = s2;

while (*p1!= '\0') p1++; //найти конец 1-ой строки.

//или while (*p1) p1++;

while ((*p1 = *p2)!= 0) {

/*копировать строку р2, пока не будет скопирован нулевой

Ограничитель*/

p1++;

p2++; //Передвинуть указатели к следующему байту

} //или while ((*p1++ = *p2++)!= 0);/*.

Пример 24.

/*Демонстрация работы с указателями и с функциями для обработки строк*/

#include "stdafx.h"

#include <stdio.h>

#include <string.h>

int main(void)

{

char string[100], temp[100], *result, simvol;

int numresult, res;

/*создает строку "computer program" посредством

использования strcpy и strcat*/

strcpy(string, "computer");

result = strcat(string," program");

printf("1) создали строку\n%s\n",result);

/*находит строку, в которой первый раз обнаружено 'a'*/

simvol='a';

result = strchr(string,simvol);

printf("2) находим в строке первое вхождение символа \'%c\'\n

%s\n",simvol,result);

/* создает копию строки */

result = strcpy(temp,string);

printf("3) создали копию строку\n%s\n",result);

/* находит "a","b","c" в строке */

strcpy(string,"xyzabbc");

res = strcspn(string,"abc");

printf("4) определяем длину заданного сегмента \n%d\n",res);

/*создает новый указатель на строку для дублирования

строки*/

result = strdup(string);

printf("5) создали новый указатель на строку \n%s\n",result);

system("pause");

return 0;

}

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

Пример 25.

/*Вывести на экран часть строки после первого пробела*/

#include "stdafx.h"

#include <stdio.h>

int main(void)

{

char s[80], *p;

int i;

printf("ввести строку: ");

gets(s);

/*найти первый пробел или конец строки*/

for(i=0; s[i] && s[i]!=' '; i++);

p = &s[i];

printf(p);

system("pause");

return 0;

}

В этой программе p будет указывать либо на пробел, если он есть, либо на ноль, если в строке нет пробелов. Если p указывает на пробел, то программа выведет на экран его и затем остаток строки. Например, если ввести фразу <язык программирования С++>, функция printf() напечатает сначала пробел и затем <программирования С++>. Если p укажет на ноль, то на экран ничего не выводится.

Пример 26:

//Выводит каждое отдельное слово и подсчитывает его длину

#include "stdafx.h"

#include <stdio.h>

#include <string.h>

int main(void)

{

char text[100],*p, *razd=".,";

int dlina;

puts ("Введите текст ");

gets(text);

p=strtok(text,razd); // Выделение первого слова текста

while (p) { // Пока можно выделить слово

dlina=strlen(p); // Определение длины слова

cout << "\n слово "<< p << " длина = " << dlina <<"\n";

p=strtok(NULL,razd);

//Выделение второго, третьего, и т.д. слов

}

system("pause");

return 0;

}

При использовании строк или указателей на строки в качестве параметров функций следует учитывать некоторые особенности.

При передаче строки как параметра функции не указывается длина, так как ограничителем является символ конца строки.

Строки передаются в функции в качестве параметров как массивы символов или как указатели типа char.

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

Обращение к строкам через указатели позволяет вносить и сохранять изменения, записанные в адресуемой области памяти. Для недопущения изменений в строке указатель на константу можно объявить с лексемой const следующим образом: const char *p;.

В силу специфики представления строк в виде символьного массива сами строки, строковые константы, заключенные в кавычки, и указатели на строки обрабатываются эквивалентно. При этом каждый такой элемент адресует область памяти и передается в функции как адрес.

При копировании строки или подстроки с использованием указателя не создается физической копии значений элементов. Объявленный новый указатель адресует то место в памяти, с которого начинается копируемая строка или подстрока. Например:

char text[50]="Язык программирования";

char *p=text, *pp;

//объявление и инициализация указателя р адресом строки text

pp=p;

//указатель рр адресует ту же строку text

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: