Загрузка...

УКАЗАТЕЛИ.


Память состоит из байтов, каждый из которых пронумерован, начиная с 0, 1, 2 … Номер – это адрес. В Си есть переменные, которые могут содержать этот адрес – указатели и операция взятия адреса — &.
int pooh=1; — определение и инициализация переменной. pooh — её
имя.
printf («%d %d\n»,pooh, &pooh); 1 12136
Машинный код команды можно выразить словами. «Выделить 2 байта памяти, присвоить им имя pooh. Поместить в ячейку с адресом 12136 число». Фактический адрес этой переменной 12136, а его символическое представление &pooh.
Значением переменной типа указатель служит адрес некоторой величины. Дадим имя этой переменной ptr; тогда можно написать ptr=&pooh;
В этом случае говорим «ptr указывает на pooh», где ptr-пере-менная, &pooh-константа.
ptr=&bah; — теперь указывает на bah.

Операция косвенной адресации *

Для доступа к переменной, адрес которой помещен в ptr, использует-ся операция косвенной адресации.
val=*ptr; //val==bah
*ptr = 10; //bah==10

Описание указателей

Мы знаем уже как описываются переменные, массивы. Как же описать указатель! Сложность в том , что переменные разных типов содержат разное число ячеек, но операции с указателями требуют знания отведенной им памяти. Поэтому, при определении указателя, мы описываем, на какой тип переменной она будет указывать, и что это указатель символ *.
int* ptr;
float* pmas;
char* pc;

Использование указателей для связи функций

Void swap(int*,int*);
Void main(void){
int x=5, y=10;
printf («Прервичные значения х=%d, y=%d\n»,x, y);
swap (&x, &y);
printf («Новые значения х=%d, y=%d\n», x, y);
}
void swap (int*v, int*z){
int u;
u=*v;
*v=*z; //x=y
*z=u;
}
Мы передали в функцию адреса переменных, поэтому при выходе х, у имееют новые значения. При передаче значений этого не происходило.
Вызов swap (x,y); swap (&x, &y);
Определение функции swap (int v, int z); swap (int*v, int*z);
Переменные х, y являются локальными в функции main, но мы таким образом можем на них воздействовать в другой функции.

Указатели на одномерные массивы

Указатели позволяют эффективно работать с массивами. Обозначение массива представляет собой скрытую форму указателя.
Mas ? &mas[0]; — определяется адрес 1-го элемента массива. Оба выражения являются константными выражениями и меняются на протяжении работы программы. Их можно присваивать переменной типа указатель.
void main(void){
int dates [4], *pti, index;
float bills [4], *ptf;
pti=dates;
ptf=bills;
for (i=0; i<4; i++)
printf («указатель +%d: %10u и %10u\n»),
i, pti+i; ptf+i);
}
Указатель +0 56014 56026 — начало адреса массивов.
+1 56016 56030
+2 56018 56034
+3 56020 56038
Прибавляя 1 к указателю, переходим к следующему элементу массива, а не к следующему байту, т.е. смещаемся на длину типа элемента масси-ва.
рt pt+1 pt+2 pt+3

dates[0] dates[1] dates[2] dates[3]
dates+2==&dates[2]
*(dates+2)==dates[2]
*dates+2==*(dates)+2

for(i=0;i<10; i++)
sum+=*(ptm+i); //Суммирование элементов массива.

Указатели на многомерные массивы

int mas[2][4], *pti;
pti=mas[0]; //pti=&mas[0][0]
pti+1?&mas[0][1]; //так как элементы массива расположены в
pti+2?&mas[1][0]; //памяти последовательно и сначала
//меняется второй индекс.
mas[0]?&mas[0][0];
mas[1]?&mas[1][0]; //Это важное свойство, потому что можно
//работать с 2-м массивом как с одинарным

Загрузка...