День до сдачи работы мы справимся, и ты получишь Отлично по своему предмету! Только представь ты занимаешься своим любимым делом, пока твои лохиодногруппники теряют свои нервные клетки Проникнись Это бесценное ощущение Курсовая,
Скачать 389.95 Kb.
|
1.8. УказателиУказатель - это переменная, содержащая адрес данных, а не их значение. Указатель используется: 1.Для связи независимых структур друг с другом. 2.Для динамического распределения памяти. 3.Для доступа к различным элементам структуры. Рассмотрим следующую программу: #include 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 #include #include #include #include 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 #include #include #include 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). Более того, использование указателей вместо индексов позволяет компилятору создавать более компактный и быстрый код. 1.9 Указатели и функции Указатели также можно использовать в качестве формальных параметров функции. Рассмотрим пример. Функция swap (обмен) объявляет два формальных параметра x и y, как указатели на данные типа int. Это означает, что функция swap работает с адресами целых переменных (а не с их значениями). Поэтому будут обработаны данные, адреса которых переданы функции во время обращения к ней. Функция main(), вызывает swap. #include swap(int *x, int *y) { int wr; wr = *x; *x = *y; *y =wr; } main() { int i,j; i = 100; j = 200; printf("Было: i=%d, j=%d\n",i,j); swap(&i,&j); printf("Стало: i =%d, j=%d\n",i,j); } После выполнения программы значения i и j поменяются местами. Необходимо отметить, что хотя указатели и экономят память, но они используют время процессора горазда больше. Таким образом, рассмотрены основные элементы языка Си. |