Большинство операций языка Си, имеющих дело со строками, работают с указателями. Рассмотрим, например, приведенную ниже бесполезную, но поучительную программу:
/* Указатели и строки */#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 = 32copy = Сообщение; значение = 14; © = 34Но изучим вывод PX(). Сначала X, который последовательно является mesg и copy, печатается как строка (%s). Здесь нет сюрприза. Все строки содержат "Сообщение".
Третьим элементом в каждой строке является &X, т. е. адрес X. Указатели mesg и copy записаны в ячейках 32 и 34, соответственно.
Теперь о втором элементе, который мы называем значением. Это сам X. Значением указателя является адрес, который он содержит. Мы видим, что mesg ссылается на ячейку 14, и поэтому выполняется copy.
|
|
Смысл заключается в том, что сама строка никогда не копируется. Оператор copy = mesg; создает второй указатель, ссылающийся на ту же самую строку.
Зачем все эти предосторожности? Почему бы не скопировать всю строку? Хорошо, а что эффективнее - копировать один адрес или, скажем, 70 отдельных элементов? Часто бывает, что адрес - это все, что необходимо для выполнения работы.
Ввод-вывод строк
fgets - прочитать строку из входного потока, включая символ новой строки.
Объявления: char *fgets (s, n, stream)char *s;int n;FILE *stream;gets - прочитать строку из стандартного файла ввода stdin.
Определение: char *gets (s)char *s;fputs - записать строку в поток stream.
Определение: int fputs (s, stream)char *s;FILE *stream;puts - записать строку в стандартный файл вывода stdout. В конце строк записывается символ новой строки.
Определение: int puts (s)char *s;