Указатель арифметики


Ранее вы узнали, что такое указатель и как управлять указателями. В этом руководстве вы изучите арифметические операции над указателями. К указателям C можно применить несколько арифметических операций: ++, -, -, +

Увеличение указателя с помощью (++)

Как и любая другая переменная, операция ++ увеличивает значение этой переменной. В нашем случае здесь переменная является указателем, поэтому, когда мы увеличиваем ее значение, мы увеличиваем адрес в памяти, на который указывает указатель. Давайте объединим эту операцию с массивом в нашем примере:

#include <stdio.h>

int main()
{
    int intarray[5] = {10,20,30,40,50};

    int i;
    for(i = 0; i < 5; i++)
        printf("intarray[%d] has value %d - and address @ %x\n", i, intarray[i], &intarray[i]);

    int *intpointer = &intarray[3]; //point to the 4th element in the array
    printf("address: %x - has value %d\n", intpointer, *intpointer); //print the address of the 4th element

    intpointer++; //now increase the pointer's address so it points to the 5th elemnt in the array
    printf("address: %x - has value %d\n", intpointer, *intpointer); //print the address of the 5th element

    return 0;
}

Уменьшение указателя с помощью (-)

Как и в нашем предыдущем примере, мы увеличили адрес указателя на единицу, используя оператор ++, мы можем уменьшить адрес, на который указывает, на единицу, используя оператор декремента (-).

#include <stdio.h>

int main()
{
    int intarray[5] = {10,20,30,40,50};

    int i;
    for(i = 0; i < 5; i++)
        printf("intarray[%d] has value %d - and address @ %x\n", i, intarray[i], &intarray[i]);

    int *intpointer = &intarray[4]; //point to the 5th element in the array
    printf("address: %x - has value %d\n", intpointer, *intpointer); //print the address of the 5th element

    intpointer--; //now decrease the point's address so it points to the 4th element in the array
    printf("address: %x - has value %d\n", intpointer, *intpointer); //print the address of the 4th element

    return 0;
}

Добавление указателей с помощью (+)

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

#include <stdio.h>

int main()
{
    int intarray[5] = {10,20,30,40,50};

    int i;
    for(i = 0; i < 5; i++)
        printf("intarray[%d] has value: %d - and address @ %x\n", i, intarray[i], &intarray[i]);

    int *intpointer = &intarray[1]; //point to the 2nd element in the array
    printf("address: %x - has value %d\n", intpointer, *intpointer); //print the address of the 2nd element

    intpointer += 2; //now shift by two the point's address so it points to the 4th element in the array
    printf("address: %x - has value %d\n", intpointer, *intpointer); //print the addres of the 4th element

    return 0;
}

Обратите внимание, как на выходе адрес сдвигается на 8 шагов в памяти. Вам может быть интересно, почему? Ответ прост: поскольку наш указатель является указателем на int, а размер переменной типа int составляет 4 байта, память может сдвигаться на 4 блока. В нашем коде мы сдвинули на 2 (добавили +2) к начальному адресу, так что получилось 2 x 4 байта = 8.

Вычитание указателей с помощью (-)

Точно так же мы можем вычесть:

#include <stdio.h>

int main()
{
    int intarray[5] = {10,20,30,40,50};

    int i;
    for(i = 0; i < 5; i++)
        printf("intarray[%d] has value: %d - and address @ %x\n", i, intarray[i], &intarray[i]);

    int *intpointer = &intarray[4]; //point to the 5th element in the array
    printf("address: %x - has value %d\n", intpointer, *intpointer); //print the address of the 5th element

    intpointer -= 2; //now shift by two the point's address so it points to the 3rd element in the array
    printf("address: %x - has value %d\n", intpointer, *intpointer); //print the address of the 3rd element

    return 0;
}

снова адрес сдвигается блоками по 4 байта (в случае int).

Прочие операции

Есть еще такие операции, как сравнение>, <, ==. Идея очень похожа на сравнение переменных, но в этом случае мы сравниваем адрес памяти.

Упражнение

Скопируйте последние три адреса intarray в parray, который представляет собой массив указателей на int.