Строки, массивы символов и указатели char*
Напомним, что базовый тип данных char понимается в Си двояко: как байт и как символ. Поэтому для указателя с типом указуемой переменной char (указатель на char ) допускаются различные интерпретации:
-указатель на отдельный байт;
-указатель на область памяти -массив байтов;
-указатель на отдельный символ;
-указатель на массив символов.
Какая из них в действительности имеет место -зависит от программы, транслятор здесь не накладывает ограничений. Тем не менее, по сложившейся традиции будем считать, что указатель на char ссылается на массив символов. А поскольку стандартным содержимым массива символов является строка - последовательность символов, ограниченная символом с кодом 0, то такой указатель логично назвать УКАЗАТЕЛЕМ НА СТРОКУ. Использование его в программе при работе со строками предпочтительнее в сравнении с массивом символов уже потому, что размерность массива символов фиксирована, а размерность памяти, адресуемой указателем, ограничивается внешними факторами. Таким образом, он является более естественным средством для представления строки.
int strlen(char *p) // Возвращает длину строки, заданной
{ // указателем на на строку char*
int n;
for (n=0; *p != '\0'; p++);
return n;
}
void strcat(char *dst, char *src)
{ // Объединяет строки,
while (*dst !='\0') dst++; // заданные указателями
for (; *src !='\0'; *dst++ = *src++);
*dst = '\0';
}
Несколько замечаний необходимо сделать о СТРОКОВЫХ КОНСТАНТАХ. Строковая константа представляет собой последовательность символов, заключенных в двойные кавычки (например "abcd"). Для строковой константы транслятор в любом контексте программы выполняет следующие действия:
-создает массив символов с размерностью, достаточной для размещения строки;
-инициализирует (заполняет) массив символами строки, дополняя символом '\0';
-в контекст программы, где присутствует строковая константа, включает указатель на созданный массив символов. Таким образом в программе ей соответствует тип char* -указатель на строку.
СТРОКОВАЯ КОНСТАНТА в любом контексте программы это указатель на создаваемый транслятором массив символов, инициализированный этой строкой.
char *q; // ПРОГРАММА
q = "ABCD";
char *q; // ЭКВИВАЛЕНТ
char A[5] = {'A','B','C','D','\0'};
q = A;
С точки зрения такого определения корректны и такие на первый взгляд " дикие" выражения:
char c,*q;
c = "ABCD"[3];
q = "12345" + 2;
for (q = "12345"; *q !='\0'; q++);
Таким образом, имя массива символов, строковая константа и указатель на строку на самом деле имеют в языке один и тот же тип char*, поэтому могут использоваться в одном и том же контексте, например, в качестве фактических параметров функций:
extern int strcmp(char *, char*);
char *p,A[20];
strcmp(A,"1234");
strcmp(p,A+2);