Указатели и массивы.

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

Указатели позволяют нам работать с символическими адресами. Поскольку в реализуемых аппаратно командах вычислительной машины интенсивно используются адреса, указатели предоставляют возможность применять адреса примерно так, как это делается в самой машине, и тем самым повышать эффективность программ. В частности, указатели позволяют эффективно организовать работу с массивами. Действительно, как мы могли убедиться, наше обозначение массива представляет собой просто скрытую форму использования указателей.

Посмотрите, что происходит со значением указателя, если к нему прибавить число.

/* прибавление к указателю */ #include<stdio.h> main () { int dates[4], *pti, index; float bills [4], *ptf; pti = dates; /* присваивает адрес указателю массива */ ptf = bills; for (index = 0; index < 4; index++ ) printf(“ ukazatel + %d: %10 u %10u\n", index, pti + index, ptf + index); }  

 

Результат работы программы

Вот результат

 

указатели + 0: 56014 56026

указатели + 1: 56016 56030

указатели + 2: 56018 56034

указатели + 3: 56020 56038

 

Первая напечатанная строка содержит начальные адреса двух массивов, а следующая строка — результат прибавления единицы к адресу и т. д. Почему так получается?

 

56014 + 1 = 56016?

56026 + 1 = 56030?

 

В нашей системе единицей адресации является байт, но тип int использует два байта, а тип float — четыре. Что произойдет, если вы скажете: «прибавить единицу к указателю?» Компилятор языка Си добавит единицу памяти. Для массивов это означает, что мы перейдем к адресу следующего элемента, а не следующего байта. Вот почему мы должны специально оговаривать тип объекта, на который ссылается указатель; одного адреса здесь недостаточно, так как машина должна знать, сколько байтов потребуется для запоминания объекта. (Это справедливо также для указателей на скалярные переменные; иными словами, при помощи операции *pt нельзя получить значение.)