- •1) Базовые элементы языка с. Алфавит и словарь языка (в1б1, в3б3)
- •2) Основные типы данных. Классификация их типов. Модификация базовых типов. (в1б2, в3б17)
- •3) Константы (в1б3, в3б2)
- •4) Переменные (в1б4, в3б16)
- •5) Структура с-программы. Понятие локальных и глобальных переменных. Функция main(). Директивы препроцессора (# include и #define). Комментарии. (в1б5, в3б1)
- •6) Операции языка с. Арифметические, логические операции. Поразрядные операции. (в1б6, в3б15)
- •7. Операции языка с. Операция присваивания и отношения. Операция определения размера. Оператор последовательного вычисления. (в1б7, в2б30)
- •8. Операции языка с. Условная операция. Операция (), операция []. (в1б8, в3б14)
- •9) Приоритет операций и порядок вычислений (в1б9, в2б29)
- •10) Основные сведения о вводе-выводе. (в1б10, в3б13)
- •11) Ввод-вывод символов (в1б11, в2б28)
- •12) Форматированный ввод-вывод. Модификаторы формата. Спецификаторы преобразования. Подавление ввода. (в3б12, в1б12)
- •13) Операторы языка с. Условные операторы (if, switch). (в1б13, в2б27)
- •14) Операторы цикла (while, for, do while )(в1б14, в3б11)
- •15) Операторы безусловного перехода ( break, continue, go to, return) (в1б15, в2б26)
- •16) Одномерные массивы. (в1б16, в3б10)
- •17) Строковый литерал. Чтение и запись строк. (в1б17, в2б25)
- •18)Двухмерные массивы. Массивы строк (в1б18, в3б9)
- •19) Инициализация массива. (в1б19, в2б24)
- •20) Способы доступа к элементом массива. (в1б20, в3б8)
- •22) Указательные переменные. Операции получения адреса (&) и раскрытие ссылка (*) (в1б22, в3б7)
- •23) Указательные выражения. Адресная арифметика. (в1б23, в2б22)
- •24) Связь массивов и указателей (в1б24,в3б6)
- •25) Функции динамического распределения памяти (в1б25, в2б21)
- •26) Динамическое выделение памяти для массивов. (в1б26, в3б5)
- •27) Функции. Определения функций. Оператор return.( в1б27, в3б20)
- •28) Функции. Прототипы функции. (в1б28, в3б4)
- •29) Функции. Вызов функций: вызов по значению и по ссылке. (в1б29, в2б19)
- •30) Передача массива в функцию. (в1б30, в3б27)
- •31) Классы памяти. Область видимости. (в2б1, в3б28)
- •32) Аргумент функции main(): argv и argc (в2б2, в3б26)
- •33) Рекурсия. (в2б3, в3б29)
- •34) Вызов библиотечных функций(в2б4, в3б25)
- •35) Директива препроцессора #define: создание макрофункций с помощью директивы #define (в2б5, в3б30)
- •36) Директивы условной компиляции #if, #else, #elif, #endif, #ifdef, #ifndef (в2б6, в3б24)
- •37) Понятие структуры. Доступ к членом структуры (в2б7)
- •38) Присваивание структур (в2б8, в3б23)
- •39) Массивы структуры(в2б9)
- •40) Передача членов структур функциям. Передача целых структур функциям. (в2б10, в3б22)
- •41) Указатели на структуры. Средство typedef (в2б11)
- •42) Понятие объединение и перечисления. Битовые поля. (в2б12,в3б21)
- •44) Методы поиска: последовательный и двоичный поиск. (в2б14, в3б20)
- •45) Основы файловой системы. Стандартные потоки. Указатель файла. Открытые файлы. Закрытые файлы. (в2б15)
- •46) Форматированный ввод-вывод в файл (в2б16, в2б17, в3б19)
- •48) Понятие очереди, стеков, связанных списков и деревьев. (в2б12, в3б18)
23) Указательные выражения. Адресная арифметика. (в1б23, в2б22)
Указательные выражения
К указателям можно применить операцию присваивания. Указатели одного и того же типа могут использоваться в операции присваивания, как и любые другие переменные.
Пример:
{
int x = 10;
int *p, *g; // объявление указателя
p = &x; // установка указателя p на переменную x
g = p; // указатель g тоже указывает на x
printf("p = %d", p); // вывод на экран содержимого p (вывод адреса)
printf("\n g = %d", g); // вывод адреса
printf("\n x = %d", x, "*g = %d", *g); /* вывод на экран величины x и величины, находящейся по адресу указателя g */
}
В языке С допустимо прмсвоить указателю любой адрес памяти. Однако, если объявлен указатель на целое число (int *p;), а по адресу, которому присвоен данному указателю, находится переменная x типа float, то при компиляции программы будет выдано сообщение об ошибке в строке p = &x. Эту ошибку можно исправить, преобразовав указатель на int к типу указателя на float явным преобразованием типа:
p = (int*)&x;
но при этом теряется информация о том, на какой тип указывал исходный указатель.
Адресная арифметика
Над указателями можно выполнять унарные операции: инкремент и декремент. При выполнении операций ++ и -- значение указателя увеличивается или уменьшается на длину типа, на который ссылается используемый указатель.
Пример:
int *ptr, a[10];
ptr=&a[5];
ptr++; // равно адресу элемента a[6]
ptr--; // равно адресу элемента a[5]
В бинарных операциях сложения и вычитания могут участвовать указатель и величина типа int. При этом результатом операции будет указатель на исходный тип, а его значение будет на указанное число элементов больше или меньше исходного.
Пример:
int *ptr1, *ptr2, a[10];
int i=2;
ptr1=a+(i+4); // равно адресу элемента a[6]
ptr2=ptr1-i; // равно адресу элемента a[4]
В операции вычитания могут участвовать два указателя на один и тот же тип. Результат такой операции имеет тип int и равен числу элементов исходного типа между уменьшаемым и вычитаемым, причем если первый адрес младше, то результат имеет отрицательное значение.
Пример:
int *ptr1, *ptr2, a[10];
int i;
ptr1=a+4;
ptr2=a+9;
i=ptr1-ptr2; // равно 5
i=ptr2-ptr1; // равно -5
Значения двух указателей на одинаковые типы можно сравнивать в операциях ==, !=, <, <=, >, >= при этом значения указателей рассматриваются просто как целые числа, а результат сравнения равен 0
(ложь) или 1 (истина).
Пример:
int *ptr1, *ptr2, a[10];
ptr1=a+5;
ptr2=a+7;
if (prt1>ptr2) a[3]=4;
В данном примере значение ptr1 меньше значения ptr2 и поэтому оператор a[3]=4 не будет выполнен.
24) Связь массивов и указателей (в1б24,в3б6)
Принято, что имя массива – адрес памяти, начиная с которого расположен массив, т.е. адрес первого элемента массива.
Идентификатор массива является константным указателем на его нулевой элемент. Например, для массива имя – это тоже самое, что &b[0], а к i-тому элементу массива можно обратиться, используя выражение *(b+i).
Для того, чтобы получить значение 6 элемента массива а, можно записать a[5] или *(a+5). Можно описать указатель, присвоить ему адрес начала массива и работать с массивом через указатель.
Следующий фрагмент программы копирует все элементы массива a в массив b:
int a[100], b[100];
int *pa = a; // или int *p = &a[0]
int *pb = b;
for (int i=0; i<100; i++)
*pb++ = *pa++; // или pb[i] = pa[i]
Для доступа к элементу многомерного массива указываются все его индексы *(matr[i]+j) или *(*(matr[i])+j). Это возможно, поскольку matr[i] является адресом начала строки массива.