Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Очень хорошо по языку С. С++.DOC
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
931 Кб
Скачать
☆

1.8. Указатели.

Указатель - это переменная, содержащая адрес данных, а не их значение. Указатель используется:

1.Для связи независимых структур друг с другом.

2.Для динамического распределения памяти.

3.Для доступа к различным элементам структуры.

Рассмотрим следующую программу:

#include <stdio.h>

main()

{

int Z,*Y;

Y =&Z;

Z = 100;

printf("Прямое значение Z: %d\n", Z);

printf("Значение Z, полученное через указатель: %d\n",*Y);

printf(" Адрес Z через получение адреса: %p\n",&Z);

printf("Адрес Z через указатель: %p\n", Y);

}

В данном примере Y указатель на целую переменную и содержит ее адрес. В свою очередь & позволяет получить адрес по которому размещено значение переменной Z. В этой программе:

- адрес переменной Z присваивается Y;

- целое значение 100 присваивается Z;

- оператор &, позволяет получить адрес,

по которому размещено значение Z.

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

Прямое значение Z: 100

Значение Z, полученное через указатель: 100

Адрес Z через получение адреса: 85B3:0FDC

Адрес Z через указатель: 85B3:0FDC

Указатели также используются для оптимального распределения памяти.

Рассмотрим пример указателя на число типа char.

#include <stdio.h>

#include <alloc.h>

#include <string.h>

#include <stdlib.h>

#include <process.h>

int main(void)

{

char *str; /* указатель на символьную переменную */

str = (char *)malloc(10);

strcpy(str, "Hello");

printf("String is %s\n", str);

free(str);

return(0);

}

Вначале по команде char *str; создан тип str, который является указателем на переменную типа char(* обозначает "указатель"). По команде str = (char *)malloc(10); выделяем 10 байт памяти под переменную str(типа строка). По команде strcpy(str, "Hello"); осуществляется - "записать в область памяти, на которую указывает str, строку символов "Hello". По команде printf("String is %s\n", str); осуществляется "напечатать на экране то, на что указывает str. Команда free(str); освобождает память, на которую указывает str.

Рассмотрим более сложный пример получения доступа к записи, используя указатель.

#include <stdio.h>

#include <string.h>

#include <alloc.h>

#include <process.h>

struct Student { /* запись Student */

char Fio[30]; /* поле записи Fio */

int Gruppa; /* поле записи Gruppa */

}; /* конец записи */

struct Student *A;

main()

{

if ((A =(Student *) malloc(sizeof(Student))) == NULL)

{

printf("Нет памяти\n");

exit(1);

}

strcpy(A[1].Fio, "Ivanov");

A[1].Gruppa=385;

printf("Fio1 %s\n Gruppa %d\n", A[1].Fio, A[1].Gruppa);

strcpy(A[2].Fio, "Petrow");

A[2].Gruppa=386;

printf("Fio2 %s\n Gruppa %d\n", A[2].Fio, A[2].Gruppa);

free(A);

}

Указатель также может использоваться для получения косвенного указателя на структуру.

Пусть poit является указателем на структуру и что elem элемент, определенный структурным шаблоном. Тогда point->elem определяет элемент, на который выполняется ссылка. Рассмотрим предыдущий пример.

struct Student { /* запись Student */

char Fio[30]; /* поле записи Fio */

int Gruppa; /* поле записи Gruppa */

}; /* конец записи */

Student *poin;

Сейчас к полям структуры мы можем обращаться несколькими способами. Эквивалентные обращения:

Student.Gruppa=236;

poin->Gruppa=236;

Отметим одну важную особенность указателей в Си. Транслятор автоматически учитывает тип указателя в арифметических действиях над ним. Например если i есть указатель на целую (т.е. двухбайтную) переменную, то действие типа i++ означает, что указатель получает приращение не один, а два байта, т.е. будет указывать на следующую переменную или элемент массива. По этой причине указатель можно использовать вместо индексов массива. Например если A - указатель на массив целого типа, то вместо A[i] можно писать *(A+i). Более того, использование указателей вместо индексов позволяет компилятору создавать более компактный и быстрый код.