Программирование на C и C++

Онлайн справочник программиста на C и C++

Сравнение указателей

Возможно сравнивать два указателя. Например, имеются указатели р и q. Тогда справедлив следующий оператор:

if(p<q) printf("р points to lower memory than q\n");

Обычно сравнение указателей используется, когда два или более указателя указывают на один объект. В качестве примера представим, что вы создается процедура, обслуживающая стек для хранения целочисленных значений. Стек - это список, построенный по принципу «первый вошел - последний вышел». Стек часто сравнивают со стопкой тарелок на столе - самая первая тарелка на столе забирается самой последней. Стек часто используется в компиляторах, интерпретаторах, электронных таблицах и другом системном программном обеспечении. Для создания стека необходимы две подпрограммы: push() и рор(). Функция push() помещает значение в стек, а роp() извлекает его. Стек содержится в массиве stack, в котором хранится STCKSIZE элементов. Переменная tos содержит адрес памяти вершины стека и используется для предотвращения переполнения или исчерпания стека. После инициализации стека данные функции могут использоваться для работы с целыми числами. Ниже показаны данные функции вместе с простой функцией main(), демонстрирующей их использование:

#include <stdio.h>
#include <stdlib.h>
#define STCKSIZE 50
void push (int i);
int pop(void);
int *p1, *tos, stack[STCKSIZE];

int main(void)
{
int value;
p1 = stack; /* присваивает p1 начало стека */
tos = p1; /* tos содержит вершину стека */
do {
printf ("Enter a number (-1 to quit, 0 to pop): ");
scanf("%d", &value);
if(value!=0) push(value);
else printf ("this is it %d\n", pop());
} while(value!=-1);
return 0;
}

void push (int i)
{
p1++;
if (p1==(tos + STCKSIZE))
{
printf("stack overflow");
exit (1);
}
*p1 = i;
}

int pop (void)
{
if(p1==tos)
{
printf("stack underflow");
exit(1);
}
p1--;
return * (p1+1);
}

Как push(), так и рор() проверяют указатель p1 для обнаружения ошибок переполнения или исчерпания. В push() p1 сравнивается с концом стека, получаемого путем сложения STCKSIZE и tos. В рор() p1 сравнивается с tos, чтобы убедиться, что стек не пуст.

В рор() в операторе return необходимы круглые скобки. Если их убрать, то оператор будет выглядеть

return *p1 + 1;

и он будет выдавать значение, хранящееся по адресу p1, увеличенное на 1, а не значение, хранящееся по адресу p1 + 1. Следует быть очень осторожным при использовании круглых скобок для достижения правильного порядка вычисления выражений с указателями.