Операции над адресами
Любое данное размещается в памяти ЭВМ и, следовательно, имеет некоторый адрес, обращаясь по которому можно извлечь данное из памяти. В языке Си определены две основные операции над адресами:
&- определение адреса операнда;
* - обращение по адресу.
Например, если bip – переменная типа int, то &bip – адрес переменной, по которому она расположена в памяти;
Если char *prt –указатель на данное типа char, то *prt – это само данное типа char (символ).
Пример операции над адресами:
# include <conio.h>
void main (void)
{
int bip;
char *prt;
bip = 2+3;
prt = ‘’Язык Turbo C\n’’
cprintf (‘’bip = %d &bip = %p\n\r’’, bip, &bip);
cprintf (‘’*prt = %c prt = %p\n\r’’, *prt, prt);
}
В результате выполнения этой программы в первой строке будет выведено значение переменной bip, равное 5 и адрес, по которому это значение размещено в памяти. Во второй строке будет выведен символ ''Я'', т.е. первый символ и адрес, по которому этот символ расположен в памяти.
Для того, чтобы более четко уяснить механизм адресации к строке символов, рассмотрим этот вопрос более подробно.
Определение местоположения строки символов и адресация к ней осуществляется с помощью указателя.
Символьные массивы (строки). Вспомним, что в языке Си переменная типа указатель объявляется следующим образом:
int *a; char *b; и т.п.
После таких объявлений а и в трактуются как переменные - указатели на соответствующий тип, a *a и *b – как сами переменные данного типа.
Переменные типа указатель содержат адрес операнда, на который они ссылаются:
Пример:
# include <conio.h>
void main (void)
{
char *st;
st = ”Язык программирования C\n”
cputs (st);
}
В результате обработки строки программы:
st =”Язык программирования C\n”
компилятор создает в тексте объектного кода машинный эквивалент этой строки, а переменной - указателю st присвоит адрес первого символа строки, т.е. адрес символа “Я”. Машинный код строки завершается специальным символом - терминатором или нулевым символом '\О'.
Команда cputs(st) воспроизведет строку символов на экране дисплея, начиная с того, который адресуется переменной st, вплоть до символа - терминатора.
Помимо определения строки символов в форме указателей существует и другая форма задания строки: в форме массива символов.
Пример:
# include <conio.h>
# include <string.h> /* файл заголовка функций, оперирующих со строками*/
void main (void)
{
char mas [24];/* описание массива из 24 символов */
strcpy (mas,’’Язык программирования С ''); /*копирование строки в массив */
cputs (mas);
}
По команде char mas [24] компилятор зарезервирует область памяти для 23 символов строки и еще один байт для размещения символа- терминатора '\О'.
Переменная mas несет информацию об адресе первого символа (нулевого элемента массива, т.к. массивы в Си нумеруются с 0: mas [0], mas[1],.. и т.д.).
Функция cputs() выведет на экран посимвольно все элементы массива. При этом каждый раз будет осуществляться проверка: не является ли очередной символ символом-терминатором.
Вот почему при размещении строки в массиве всегда необходимо отводить как минимум на один элемент больше для '\О', или определяйте необходимый размер в памяти по умолчанию:
char mas[]=’’Строка символов''; /* Размер массива не задан */.
Отметим, что функция cputs() и strcpy() работают с формальными параметрами типа указатель. Их прототипы имеют следующий вид:
int cputs (char* string);
char strcpy (char*dest, char* sours).
Это значит, что при вызове этих функций им должны в качестве фактических параметров передаваться адреса. Но в нашей программе нигде не встречается символ &. В чем же дело?
В том, что при описании массива его имя трактуется как указатель на его первый элемент, т.е.
mas эквивалентно & mas[0] |
Дата добавления: 2017-06-02; просмотров: 371;