Указатели и строки

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

/* Указатели и строки */

#define PX(X) printf("X = %s; значение = %u; &X = %u\n",X,X,&X)

main()

{

static char *mesg = "Сообщение";

static char *copy;

copy = mesg;

printf("%s\n",copy);

PX(mesg);

PX(copy);

}

Мы можем подумать, что эта программа копирует строку "Сообщение", и при беглом взгляде на вывод может показаться правильным это предположение:

Сообщение

mesg = Сообщение; значение = 14; &mesg = 32

copy = Сообщение; значение = 14; &copy = 34

Но изучим вывод PX(). Сначала X, который последовательно является mesg и copy, печатается как строка (%s). Здесь нет сюрприза. Все строки содержат "Сообщение".

Третьим элементом в каждой строке является &X, т. е. адрес X. Указатели mesg и copy записаны в ячейках 32 и 34, соответственно.

Теперь о втором элементе, который мы называем значением. Это сам X. Значением указателя является адрес, который он содержит. Мы видим, что mesg ссылается на ячейку 14, и поэтому выполняется copy.

Смысл заключается в том, что сама строка никогда не копируется. Оператор copy = mesg; создает второй указатель, ссылающийся на ту же самую строку.

Зачем все эти предосторожности? Почему бы не скопировать всю строку? Хорошо, а что эффективнее - копировать один адрес или, скажем, 70 отдельных элементов? Часто бывает, что адрес - это все, что необходимо для выполнения работы.

Операция вычисления размера (в байтах) sizeof действует для объектов символьного типа и строк.

Пример 1.

// Определение размера строк

#include "stdafx.h"

#include <stdio.h>

int main(void)

{

char s1[10]="string1";

int k=sizeof(s1);

printf("%s\t%d\n",s1,k);

char s2[]="string2";

k=sizeof(s2);

printf("%s\t%d\n",s2,k);

char s3[]={'s','t','r','i','n','g','3','\0'};

/*окончание строки '\0' следует соблюдать, формируя

в программах строки из отдельных символов*/

k=sizeof(s3);

printf("%s\t%d\n",s3,k);

char *s4="string4";

//указатель на строку, ее нельзя изменить

k=sizeof(s4);

printf("%s\t%d\n",s4,k);

system("pause");

return 0;

}

Результат выполнения программы:

string1 10 – выделено 10 байтов, в том числе под '\0'

string2 8 – выделено 8 байтов (7 + 1 байт под '\0')

string3 8 – выделено 8 байтов (7 + 1 байт под '\0')

string4 4 – выделено 4 байта


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



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