Язык Си - руководство для начинающих
Шрифт:
printf("Среднее из заданных значений %d.\n", mean(numbs,size));
/* находит среднее значение массива из n целых чисел */
int mean(array, n);
int array[ ], n;
{
int index;
long sum; /* Если целых слишком много, их можно
суммировать в формате long int */
if(n > 0)
{
for(index = 0, sum = 0; index < n; index++)
sum + = array[index];
return((int)(sum/n)); /*
else {
printf("Нет массива. \n");
return(0); }
}
Эту программу легко переделать, применяя указатели. Объявим ра указателем на тип int. Затем заменим элемент массива array[index] на соответствующее значение: *(ра + index).
/* Использование указателей для нахождения
среднего значения массива n целых чисел */
int mean(pa, n) int oра, n;
{
int index;
long sum; /*Если целых слишком много,
их можно суммировать в формате long int */
if(n > 0)
{
for(index=0, sum=0; index < n; index++)
sum + = *(pa + index);
return((int)(sum/n)); /* Возвращает целое */ }
else {
printf("Нет массива.\n");
return(0); }
}
Это оказалось несложным, но возникает вопрос: должны ли мы изменить при этом вызов функции, в частности numbs, который был именем массива в операторе mean(numbs, size)? Ничего не нужно менять, поскольку имя массива является указателем. Как мы уже говорили в предыдущем разделе, операторы описания:
int ра[ ];
и
int *ра;
идентичны по действию: оба объявляют ра указателем. В программе можно применять любой из них, хотя до сих пор мы использовали второй в виде *(ра + index).
Понятно ли вам, как работать с указателями? Указатель устанавливается на первый элемент массива, и значение, находящееся там, добавляется в sum. Затем указатель передвигается на следующий элемент (к указателю прибавляется единица), и значение, находящееся в нем, также прибавляется к sum и т. д. Это похоже на механизм работы с массивом, где индекс действует как стрелка часов, показывающая по очереди на каждый элемент массива.
Теперь
ОПЕРАЦИИ С УКАЗАТЕЛЯМИ
Что же мы теперь умеем делать с указателями? Язык Си предлагает пять основных операций, которые можно применять к указателям, а нижеследующая программа демонстрирует эти возможности. Чтобы показать результаты каждой операции, мы будем печатать значение указателя (являющегося адресом, на который ссылается указатель), значение, находящееся по этому адресу, и адрес самого указателя.
/* операции с указателями */
#define PR(X)
printf("X = %u,*X = %d, &X = %u\n",X, *X,&X);
/* печатает значение указателя (адрес),
значение, находящееся по */
/* этому адресу, и адрес самого указателя */
main
static int urn[ ] = [100, 200, 300];
int *ptrl, *ptr2;
{
ptrl = urn; /* присваивает адрес указателю */
ptr2 = &urn [2]; /* то же самое */
PR(ptrl); /* см. макроопределение, указанное выше */
ptrl++; /* увеличение указателя */
PR(ptrl);
PR(ptr2);
++рtr2; /* выходит за конец массива */
PR(ptr2);
printf("ptr2 - ptrl = %u\n", ptr2 - ptrl);
}
В результате работы программы получены следующие результаты:
ptrl = 18, *ptrl = 100, &ptrl = 55990
ptrl = 20, *ptrl = 200, &ptrl = 55990
ptr2 =22, *ptr2 = 300, &ptr2 = 55992
ptr2 =24, *ptr2 = 29808, &ptr2 = 55992
ptr2 - ptrl = 2
Программа демонстрирует пять основных операций, которые можно выполнять над переменными типа указатель.