- •Введение.
- •Глава 1. Основы языка Си.
- •Алфавит.
- •1.2. Основные конструкции Си.
- •1.3.2. Ввод.
- •1.4. Базовые типы данных Языка Си.
- •1.4.1. Идентификаторы.
- •1.4.2. Типизированные константы.
- •1.4.3.1. Целые типы.
- •1.4.3.2. Вещественные типы.
- •1.4.3.3. Символьные типы.
- •1.4.4. Тип данных строка.
- •1.4.3. Переменные.
- •1.4.5. Структуры.
- •1.4.5.1. Массивы.
- •1.4.5.2. Записи.
- •1.4.6. Область видимости и время жизни переменных.
- •1.5. Основные операторы.
- •1.6. Препроцессор.
- •1.7. Программы. Функции.
- •1.8. Указатели.
- •1.9. Указатели и функции.
- •1.10. Файлы.
- •1.11. Дополнительные функции Си.
- •1.11.1. Функции преобразования.
- •1.11.2. Преобразования символьных строк: atoi(), atof().
- •1.11.3. Функции, работающие со строками.
- •1.12. Особенности программирования на языке Си.
- •1.12.1. Модули. Многомодульное программирование.
- •1.12.2. Модели памяти.
- •1.12.3 Программирование в dos и Windows
- •1.12.4 Использование языка ассемблера в программах на Си.
- •Глава 2. Примеры использования языка Си.
- •2.1. Сортировка.
- •2.2. Рекурсивные алгоритмы.
- •2.3. Задача Ханойские башни.
- •3.2.1. Классы.
- •3.2.2. Перегрузка функций.
- •3.2.3. Конструкторы.
- •3.2.4. Деструкторы.
- •3.2.5. Конструкторы с параметрами.
- •3.2.6. Введение в наследование.
- •3.2.7.Виртуальные функции.
- •3.2.8. Указатели на объекты.
- •4.2. Компоненты vcl. Свойства, события, методы.
- •В отличие от свойств методы не видны в окне инспектора объектов.
- •4.2.1.Типы компонент
- •4.2.2. Иерархия классов vcl
- •4.4.Визуальные компоненты (vcl).
- •4.5. Программы, управление событиями, исключения.
- •4.6.Стратегия отладки Windows-программ.
- •4.7.Использование компонент vcl в разработке программ.
- •4.8.Графические компоненты.
- •4.9.Мультимедиа.
- •4.10.Спрайтовая графика.
- •4.11. Объектная технология ole2.
- •4.12.Библиотеки dll.
- •4.13.Разработка визуальных компонент.
- •4.14. Введение в программирование cgi.
- •4.15. Программирование баз данных.
- •4.16. Пакеты.
- •Заключение.
- •Литература:
- •Глава 1. Основы языка Си. 4с.
- •Глава 2. Примеры использования языка Си. 48c.
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). Более того, использование указателей вместо индексов позволяет компилятору создавать более компактный и быстрый код.
