Перейти к основному содержимому

Арифметика указателей

Арифметические операции (сложение, вычитание, инкремент, декремент) с указателями производятся немного иначе, чем с числами. Рассмотрим вначале операции инкремента и декремента и возьмем для этого указатель на объект типа int. Операция инкремента (увеличения на единицу) будет означать увеличение адреса, который хранится в указателе, на размер типа указателя. То есть в данном случае указатель на тип int, а размер объектов int в большинстве архитектур равен 4 байтам. Поэтому увеличение указателя типа int на единицу означает увеличение значение указателя на 4. Соответственно, для указателя типа short эти операции изменяли бы адрес на 2, а для указателя типа char на 1. Пример с типом int:

#include <stdio.h>

int main( void )
{
int n = 10;
int *ptr = &n;

printf("address=%p \t value=%d \n", (void*)ptr, *ptr);

ptr++;

printf("address=%p \t value=%d \n", (void*)ptr, *ptr);

ptr--;

printf("address=%p \t value=%d \n", (void*)ptr, *ptr);

return 0;
}

Аналогично указатель будет изменяться при прибавлении/вычитании не единицы, а любого другого целого числа.

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

#include <stdio.h>

int main( void )
{
int a = 10;
int b = 23;
int *pa = &a;
int *pb = &b;

ptrdiff_t c = pa - pb;  // разница между адресами

printf("pa=%p \n", (void*)pa);
printf("pb=%p \n", (void*)pb);
printf("c=%lld \n", c);

return 0;
}

Результатом разности двух указателей является "расстояние" между ними, которое соответствует количеству значений типа указателя (в примере выше типа int), которые могут поместиться между этими двумя указателями. Например, если адрес из первого указателя на 4 больше, чем адрес из второго указателя (0x0060FE9C + 4 = 0x0060FEA0), а размер одного объекта равен 4 байтам, то расстояние между указателями будет равно (0x0060FEA0 - 0x0060FE9C)/4 = 1.

Расстояние между указателями представляет тип ptrdif_t - на 64-разрядной архитектуре этот тип является псевдонимом для базового типа long long и занимает 8 байт.

Самостоятельная работа

Задачи

Задача 1

Посчитать количество слов в тексте, слова разделены одним или несколькими пробелами. Попробуйте решить данную задачу с использованием функции getchar().