Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Электронный конспект лекций (семестр 2).doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
251.39 Кб
Скачать

1.1.6.Связь указателей и строк

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

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

Строковая константа может быть "при­своена" указателю на тип char:

char* s1 = "The string";

В приведенном объявлении указатель на константные символьные данные s1 инициализируется адресом строковой константы "The string".

Следует отметить отличие данного объявления от объявления

char s2[] = "The string";

Первое из приведенных объявлений формирует указатель s1 размером в четыре байта, содержащий адрес строковой константы "The string", второе – массив символов s2 размером в 11 байтов (длина строки "The string" плюс нулевой символ) с соответствующими начальными символьными значениями. Соответственно, различаются и способы работы с объявленными данными: элементы массива s2 можно изменять, а данные, на которые указывает s1, вообще говоря, нет.

Второе объявление можно рассматривать как краткую форму записи объявления

char s2[] = {'T','h','e',' ','s','t','r','i','n','g','\0'};

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

Символьные функции работают с отдельными символами и требуют включения в программу директивы

#include <ctype.h>

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

#include <string.h>

1.1.7.Преобразование указателей

Указатель на данные одного типа может быть преобразован в указа­тель на данные другого типа. Однако при этом следует учитывать, что данные, адресуемые преобразованным указателем, будут интерпретироваться по-новому (может измениться их размер, а, следовательно, и значе­ние). Преобразование указателей выполняется операцией приведения типа:

( тип *) указатель

Например, операторы:

short int i = 0x1010; // Это десятичное 1*4096+ 1*16 = 4112

short *ptr = &i;

short int j = *ptr;

short int k = *(char*)ptr;

приведут к созданию переменной j с начальным значением 0x1010 и переменной k с начальным значением 0x10.

1.1.8.Бестиповые указатели

Бестиповый указатель (указатель на неопределенный тип) позволяет отсрочить определение типа, на который ссылается указатель, или использовать один указатель для обращения к данным разных типов. При объявлении такого указателя вместо типа адресуемых им данных указывается ключевое слово void:

void * имя_указателя ;

Переменная, объявленная как указатель на тип void, может быть использована для работы с данными любого типа. Но для того, чтобы оперировать бестиповым указателем или данными, которые он адресует, необходимо явно указать требуемый тип в каждой операции с таким указателем. Это можно сделать с помощью операции приведения типа:

int a = 125;

double d = 10.3975;

short b[4] = {0, 1, 2, 3};

void *vp;

. . .

vp = &a;

cout << *(int*)vp << endl; // Вывод значения переменной a

vp = &d;

cout << *(double*)vp << endl; // Вывод значения переменной d

vp = b;

cout << *((short*)vp+1) << endl; // Вывод значения b[1]

vp = (short*)vp+2; // Изменение значения vp

cout << *(short*)vp << endl; // Вывод значения b[2]

Переменная vp объявлена как бестиповый указатель, поэтому ей можно присвоить адрес переменной любого типа. Однако ни одна операция не может быть выполнена над бестиповым указателем до тех пор, пока не будет явно задан тип данных, на кото­рый он указывает. В примере указатель vp с помощью операции приведения типа преобразуется к типам int*, double* и short*.