- •Фрагмент, запрашивающий у пользователя 10 целых чисел,
- •Доступ к элементам многомерного массива в
- •Типичные ошибки программирования
- •скалярные производные типы, в том числе:
- •Признак переменной-указателя для компилятора -
- •Указатели при их описании могут, как и обычные
- •Оператор присваивания
- •Существуют ограничения и на использование
- •Сам указатель-переменная тоже имеет адрес.
- •во всех случаях использования указателя,
- •Для указателей-переменных разрешены следующие
- •Использование механизма указателей - один из
- •Использование указателей дает несколько более
- •Элементы массива - любой тип, в том числе и
- •Преимущества использования массивов - появляется
- •Структурирование обработки данных: Составной
- •Каждая инициализация auto или register переменных
- •Макросы – символическое имя некоторых операций,
- •Функции - программные блоки, которые могут
- •Определение переменной в дополнении к ее имени и
- •Перед использованием функцию надо определить, задав
- •Список параметров, заключаемый в скобки, в
- •имя_функции(список_фактических_параметров)
- •вызов. . . ф-и
- •Уже знаете, что существуют функции, не требующие для
- •Как правило (хотя формально не обязательно), кроме
- •Передача в функцию параметров
- •По адресу, когда в функцию передается не
- •void Unit(int*,int); /*Прототип функции Unit()*/
- •В примере - в функцию передаются данные – адрес и
- •По ссылке, когда в функцию также передается
- •Сравнение методов передачи в функцию параметра по адресу и по ссылке
- •Типичные ошибки программирования
- •Типичные ошибки программирования
- •Параметры со значениями по умолчанию
Сам указатель-переменная тоже имеет адрес.
Поэтому, например, корректным будет такой фрагмент:
int var1, *ptr1,*ptr2=&var1; ptr1=(int*)&ptr2;
Здесь описываются два указателя-переменные и ptr2 инициализируется значением адреса переменной varl. Затем ptrl присваивается значение адреса, по которому в памяти располагается ptr2.
Особым типом указателя является указатель типа void *, называемый часто родовым (generic). Ключевое слово void говорит об отсутствии данных о размере объекта в памяти. Но компилятору для корректной интерпретации ссылки на память через указатели нужна информация о числе байт, участвующих в операции.
во всех случаях использования указателя,
описанного как void *, необходимо выполнить операцию явного приведения типа указателя. unsigned long block = 0xFFEEDDCCL;
void* ptr=█ char ch;
unsigned two bytes;
ch = * (char*) ptr; two_bytes = *( unsigned*) ptr;
Указатель-переменная ptr инициализируется значением адреса первого байта переменной block. При выполнении присваивания компилятору необходимо знать размер объекта справа от знака =. Эту информацию сообщают компилятору операции приведения типа void * к типу (char *), (unsigned *), (long int *). В первой операции присваивания операнд слева – это первый байт переменной block. Поэтому переменная ch становится равной 0хСС. (Напомним, что младший байт всегда
располагается в памяти по меньшему адресу.) Во второй
Для указателей-переменных разрешены следующие
операции:присваивание;
инкремент или декремент;сложение или вычитание;сравнение.
Язык С (С++) разрешает операцию сравнения указателей одинакового типа. При выполнении присваивания значение указателя в правой части выражения пересылается в ячейку памяти, отведенную для указателя в левой части.
Если к указателю, описанному как type * ptr; , прибавляется или отнимается константа N, значение ptr изменяется на N * sizeof(type). Разность двух указателей type * ptrl, * ptr2 – это разность их значений, поделенная на sizeof(type).
Использование механизма указателей - один из
способов доступа к элементам массива. Массив - это расположенные вплотную друг за другом в памяти элементы одного и того же типа. Каждый массив имеет имя, оно является указателем-константой, равной адресу начала массива (первого байта первого элемента массива). Можно: доступ к отдельным элементам массива по имени массива и индексу (порядковому номеру) элемента, рассматривая имя как указатель и используя операцию *.
Будут полностью эквивалентными ссылки на i-й элемент массива array (независимо от типа элемента) array [i] и *(array + i).
аrrау &аrrау[0], ((array + i) &аггау [i]).
Использование указателей дает несколько более
короткий код программы и в ряде случаев позволяет обойтись без дополнительных переменных, используемых в качестве индексов.
Имя двумерного массива является указателем-
константой |
на |
массив |
указателей-констант. |
||
Элементами массива |
|
Для двумерного массива m |
|||
константы на начало |
|
||||
matrix[2][2] |
указателями |
возможны |
следующие |
||
первую и вторую строки |
способы |
индексации для |
|||
matrix[2], причем: |
|
доступа к ij-му элементу |
|||
matrix[0] &matrix[0][0], |
массива: |
|
|||
matrix[1] &matrix[1][0], |
m[i][j], |
|
|||
matrix[2] &matrix[2][0]. |
*(m[i]+j)), |
|
|||
Как и для одномерных |
*(*(m + i) +j)). |
||||
двумерного массива может помощью механизма указателей, причем "точкой
отсчета" может быть как самый первый элемент
массива, так и первый элемент каждой из строк, т. е.
Элементы массива - любой тип, в том числе и
указатели-переменные: для компактного располо- жения в памяти строк текста, структурных переменных и других "протяженных" объектов данных, такие массивы указателей удобны при динамическом управлении памятью.
Как и любой другой массив, массив указателей должен описываться, причем может выполняться инициализация отдельных элементов:
char * messages[20]; //массив указателей из 20 элементов
Каждый элемент массива messages имеет тип char *.
Число байт памяти, занимаемых элементом, зависит от модели памяти (2 или 4 байта).
Описание массива указателей с инициализацией: char * messages[ ] = {"Не открыт файл",
"Ошибка ввода", "Диск", "Тайм-аут",};
Компилятор резервирует место для 4 указателей. Они получают начальное значение, равное адресу начала в памяти соответствующих строковых литералов.
Существует принципиальное различие в расположении в памяти массива указателей и, на первый взгляд, подобного ему двухмерного массива типа char, например, такого:
char array [ ][16] = { "Не открыт файл", "Ошибка ввода", "Диск", "Тайм-аут", };
Преимущества использования массивов - появляется
возможность манипулировать не самими объектами, а только их адресами выигрыш в скорости выполнения программы. Объекты, с кот. работает программа, могут распола-гаться в выделяемой динамически области памяти.
Имя массива указателей является указателем- константой на I элемент массива. Первый элемент
массива сам является указателем имя массива указасторожно!!!елей является указателем а указатель.
В С (C++) м жно описать и переменную, имеющую тип "указатель на указатель". Приз ак м такого типа является повторение символа * при описании переменной. Число символов * определяет число "уровней" указателя. Фактически указатель на указатель – это ячейка памяти, хранящая адрес указателя. Размер области памяти, выделяемой для
такой переменной, зависит от модели памяти. При
Структурирование обработки данных: Составной
оператор ("блок", что эквивалентно) дает возможность использовать несколько операторов в том месте, где предполагается использование одного:
составной_оператор:
{
список_описаний optional список_операторов optional
}
Блоки могут быть вложенными список_описаний:
описание описание список_описаний
список_операторов: оператор
оператор список_операторов Если какой-либо из идентификаторов в
списке_описаний был ранее описан, то внешнее
описание выталкивается на время выполнения блока,
Каждая инициализация auto или register переменных
производится всякий раз при входе в начало блока. В блок можно делать передачу; в этом случае инициализации не выполняются. Инициализации переменных, имеющих класс памяти static осуществляются только один раз в начале выполнения программы.
#include<stdio.h> long k=0;
void main()
{
int k=1; |
|
|
|
|
|
|
int k |
|
|||
{ |
|
|
|
|
|
|
|
char k |
|
|
|
printf(“%d”, k); |
|
|
|
|
|
|
|
|
|
|
|
char k = 'A'; |
|
|
|
|
|
|
|
|
|
|
|
printf(“%c”, k); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
printf(“%c”, k); |
|
|
|
|
|
} |
|
|
|
|
|
