Вівторок, 19.03.2024, 05:00
Гость

Мішатронік

Мобільна версія | Додати у вибране  | Мій профіль | Вихід | RSS |
Меню сайту
Наше опитування
Яка мова вам ближче?
Всього відповідей: 11
Статистика

Онлайн всього: 1
Гостей: 1
Користувачів: 0


Строковые константы

Строковая константа представляется последовательностью символов кода ASCII, заключённой в кавычки: "...". Она имеет типchar[].

 

Примеры:

 
"This is character string"
"Это строковая константа"
"A" "1234567890" "0" "$"
 

В конце каждой строки компилятор помещает нулевой символ ' \0 ', отмечающий конец данной строки.

 

Каждая строковая константа, даже если она идентична другой строковой константе, сохраняется в отдельном месте памяти.

 

Если необходимо ввести в строку символ кавычек ( " ), то перед ним надо поставить символ обратной косой ( \ ). В строку могут быть введены любые специальные символьные константы, перед которыми стоит символ \.

 

Символ \ и следующий за ним символ новой строки игнорируется.

 

Строковые константы размещаются в статической памяти. Вся фраза в кавычках является указателем на место в памяти, где записана строка. Это аналогично использованию имени массива, служащего указателем на расположение массива. Если это действительно так, то как выглядит оператор, который выводит строку?

 
/* Строки в качестве указателей */
main( )
{
 printf("%s, %u, %c\n", "We", "love", *"Pascal");
}
 

Итак, формат %s выводит строку We. Формат %u выводит целое без знака. Если слово "love" является указателем, то выдается его значение, являющееся адресом первого символа строки. Наконец, *"Pascal" должно выдать значение, на которое ссылаетсяадрес, т.е. первый символ строки "Pascal".

 

Вот что выдаст наша программа:

 
We, 34, P
 

Массивы символьных строк и их инициализация

При определении массива символьных строк необходимо сообщить компилятору требуемый размер памяти. Один из способов сделать это - инициализировать массив при помощи строковой константы. Например, оператор

 
char m1[ ]="Только ограничьтесь одной строкой.";
 

инициализировал внешний по умолчанию массив m1 для указанной строки. Этот вид инициализации является краткой формой стандартной инициализации массива

 
char m1[ ]={
'T','o','л','ь','k','o','
','o','г'','p','a','н','и','ч','ь','т','e','c','ь',' 
'o','д','н','o','й',' 
','c','т','p','o','k','o','й','.','\0'
}
 

Без символа 0 мы имеем массив символов, а не строку. Для той и другой формы компилятор подсчитывает символы и таким образом получает размер памяти. Как и для других массивов, имя m1 является указателем на первый элемент массива:

 
m1 == &m1[0], *m1 == 'T', и *(m1+1) == m1[1] == 'o'
 

и т.д.

 

Действительно, мы можем использовать указатель для создания строки. Например:

 
char *m3="\n Символьная строка.";
 

Это почти то же самое, что и

 
static char m3[ ]="\n Символьная строка.";
 

Оба описания говорят об одном: m3 является указателем строки со словами "Символьная строка". В том и другом случае сама строка определяет размер памяти, необходимой для ее размещения. Однако вид их не идентичен.

Массив и указатель: различия

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

 
static char heart[ ] = "Я люблю язык Cи!";
char *head = "Я люблю язык Pascal!";
 

Основное отличие состоит в том, что указатель heart является константой, в то время как указатель head - переменной. Посмотрим, что на самом деле дает эта разница.

 

Во-первых, и в том и в другом случае можно использовать операцию сложения с указателем:

 
for(i=0;i<7;i++)
putchar(* (heart+i));
putchar('\n');
for(i=0;i<7;i++)
putchar(* (head+i));
putchar('\n');
 

В результате получаем

 
Я люблю
Я люблю
 

Но операцию увеличения можно использовать только с указателем:

 
while ((*head) != '\0') /* останов в конце строки */
putchar(*(head++)); /* печать символа и перемещение указателя */
 

В результате получаем:

 
Я люблю язык Pascal!
 

Предположим, мы хотим изменить head на heart. Можно так:

 
head=heart; /* теперь head указывает на массив heart */
 

но теперь можно и так

 
heart = head; /* запрещенная конструкция */
 

Ситуация аналогична x = 5 или 5 = x. Левая часть оператора присваивания должна быть именем переменной. В данном случаеhead = heart, не уничтожит строку про язык Cи, а только изменит адрес , записанный в head.

 

Вот каким путем можно изменить обращение к head и проникнуть в сам массив:

 
heart[13] = 'C';
 

или

 
*(heart+13)='C';
 

Переменными являются элементы массива, но не имя!

 

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

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

 
/* Указатели и строки */
#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 отдельных элементов? Часто бывает, что адрес - это все, что необходимо для выполнения работы.

 

Форма входа
Пошук
Друзі сайту
Календар
«  Березень 2024  »
ПнВтСрЧтПтСбНд
    123
45678910
11121314151617
18192021222324
25262728293031

Єдина Країна! Единая Страна!