Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Vstup.docx
Скачиваний:
47
Добавлен:
28.09.2019
Размер:
6.42 Mб
Скачать

1.4.12. Оператор goto

Использование оператора безусловного перехода goto в практике программирования на языке СИ настоятельно не рекомендуется, так как он затрудняет понимание программ и возможность их модификаций.

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

goto имя-метки;

...

имя-метки: оператор;

Оператор goto передает управление на оператор, помеченный меткой имя-метки. Помеченный оператор должен находиться в той же функции, что и оператор goto, а используемая метка должна быть уникальной, т.е. одно имя-метки не может быть использовано для разных операторов программы. Имя-метки - это идентификатор.

Любой оператор в составном операторе может иметь свою метку. Используя оператор goto, можно передавать управление внутрь составного оператора. Но нужно быть осторожным при входе в составной оператор, содержащий объявления переменных с инициализацией, так как объявления располагаются перед выполняемыми операторами и значения объявленных переменных при таком переходе будут не определены.

8.2 Одновимірні та багатовимірні масиви. Покажчики. Масиви динамічної пам’яті.

3 С++. Одновимірні масиви даних: визначення, ініціалізація, доступ до елементів масиву. Організація введення-виведення елементів масивів даних.

Массив – совокупность переменных одного типа. В массиве хранятся элементы , которые имеют одно имя и отличаются индексом.

Одномерные массивы:

тип имя_массива [ размер]

где тип- задает тип элементов объявляемого массива. Элементами массива не могут быть функции и элементы типа void.

имя массива - – это идентификатор массива

размер – целочисленное константное выражение в квадратных скобках, задает количество элементов массива.

Массив может определяться следующими способами:

1) числовой константой int a1[10];

2) с помощью const const int M=4;

float b1[M];

float b2[M+2];

3) с помощью директивы define #define N 20:

char c1[N];

Инициализация массива – присвоение начальных значений элементов при определении массива. Элементы массива инициализируются:

1)неявно(поумолчанию). Внутри статические массивы заполняются нулями, а внешние произвольными значениями.

2)явно. Явно массив может инициализироваться двумя способами: полная и неполная инциализация.

Полная инициализация – после определения массива ставится знак «=» и через «,» присваиваются значения элементам массива. int a1[5]={1,2,3,4,5} При полной явной инициализации размер массива можно не указывать. int a2[]={1,2,3,4,5}

Неполная инициализация int a1[]={1,2,3} – остальным элементам присваиваются значение нуля или мусор.

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

Ввод массивов может осуществляться несколькими способами:

-передача данных в виде параметров командной строки при запуске программы;

-в цикле запрос-ответ, когда программа сама запрашивает значения элементов массивов, а пользователь вводит их с клавиатуры;

-чтение данных массивов из текстовых или бинарных файлов.

Вывод массивов может осуществляться как на экран дисплея, так и в текстовые или бинарные файлы.

4 С++. Багатовимірні масиви даних: визначення, розташування в пам'яті, ініціалізація, доступ до елементів массиву

Многомерный массив – массив массивов ( массив, элементы которого являются массивы)

Определение многомерного массива:

тип имя_массива [n1][n2]….[nk]

где тип- задает тип элементов объявляемого массива. Элементами массива не могут быть функции и элементы типа void.

имя массива - – это идентификатор массива

n1…nk-1 размер – целочисленное константное выражение в квадратных скобках, задает количество в массиве массивов размерности (k-1).

Общее количество элементов: n1*n2*… nk

Пример: int a[2][3]={1,2,3,4,5,6}

for(int i=0;i<2;i++)

for(int j=0;j<3;j++)

cout<<&a[i][j]<<” “<<a[i][j]<<”\n”

На экране: 0x8b10off4 1

0x8b10off4 1

0x8b10off6 2

0x8b10off8 3

0x8b10offA 4

0x8b10offC 5

0x8b10offE 6

Расположение массива в памяти:

Доступ к элементам многомерного массива осуществляется

1) через индексы.

int b[5][3][6]; // массив

b[5][3][6]=100; // последний элемент массива

2) с помощью указателей( разыменование массива)

*(a[1]+2) или *(*(a+1)+2)

Пример: cout<<”a=”<<a; // 0x8b10off4 (1)

cout<<”a[0]=”<<a[0]; // 0x8b10off4 (1)

cout<<”a[1]=”<<a[1]; // 0x8b10offA (4)

cout<<”a[1]=”<<*(а+1); // 0x8b10offA (4)

cout<<”a[1][1]=”<<*(*(a+1)+1); // 0x8b10offC (5)

cout<<”sizeof(a);// 12b

cout<<”sizeof(&a);// 12b

cout<<”sizeof(a[1]);// 6b

cout<<”sizeof(a[1][0]);// 2b

cout<<”sizeof(&a[][0]);// 4b

Инициализация многомерного массива:

1)неявно(поумолчанию). Внутри статические массивы заполняются нулями, а внешние произвольными значениями.

2)явно. Явно массив может инициализироваться двумя способами: полная и неполная инициализация. При явной инициализации допускается не указывать самую левую размерность массива.

Явная полная – int b[2][2]={1,2,3,4};

Int a[2][3]={{1,2,3},{9,10,11}};

При явной полной инициализации можно вводить дополнительные фигурные скобки.

Явная неполная- int a[5][4]={1,2,3};

int k[3][4]={{1,2},{1,2}};

5 С++. Покажчики. Визначення, ініціалізація і операції над покажчиками. Зв'язок масивів та покажчиків.

Указатель – это целая беззнаковая переменная, содержащая адрес памяти какого-либо объекта программы. Указатель может содержать адрес переменной, массива, структуры, другого указателя, функции. Для определения (создания) указателя используется запись:

тип *имя_указателя;

где тип указателя – это тип переменной, адрес которой содержит указатель.

int *ptri; // указатель на переменную типа int.

float *ptrf; // указатель на переменную типа float.

Каждое из этих определений выделяет в памяти ячейки для переменной типа указатель. Размер памяти, занимаемый указателем, можно определить: sizeof(имя_указателя). Например, int sz1=sizeof(ptri); int sz2=sizeof(ptrf);

В общем случае под указатель выделяется 4 байта для модели памяти large (2 байта – сегмент и 2 байта – смещение). Но сам указатель ни на что не указывает. Чтобы далее использовать эти указатели в программе, необходимо присвоить им конкретные значения с помощью операции присвоения, либо путем инициализации.

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

  • адрес переменной, который можно получить с помощью операции &;

  • указатель, уже имеющий значение;

  • явно заданный адрес памяти.

Указатели можно инициализировать:

тип *имя_указателя=инициализирующее выражение;

Фрагмент программы с примерами инициализации:

Пример.

int a=11;int *ptra, *ptrb;

ptra =&a;// указателю присвоили адрес переменной a

ptrb=ptra; //указателю присвоили содержимое указателя ptra

printf("%d %p %p %p %p %p\n",a,&a,ptra,&ptra,ptrb,&ptrb);

char*vb=(char*)0xB8000000;//начальный адрес видеопамяти

printf("vb=%p &vb=%p",vb,&vb); // vb=B800:0000 &vb=8ABF:0FF6

В результате работы этого фрагмента получим:

11  8ADA:0FFE  8ADA:0FFE  8ADA:0FFA  8ADA:0FFE  8ADA:0FF6

vb=B800:0000 &vb=8ABF:0FF6

Указатель очень часто используются для обращения (доступа) к объекту, на который указывает указатель. Этот процесс называют разыменованием и выполняется он с помощью операции разыменования (разадресации) "*". Рассмотрим пример с операцией разыменования:

Пример .

float f=1.3, *pf=&f;

cout<<"pf="<<pf; // pf=0xF9B00FFC

cout<<" *pf="<<*pf; // *pf=1.3

*fp=2.7;

cout<<" f="<<f; // f=2.7

Операция разыменования дает содержимое области памяти, на которую указывает указатель, которое может быть любого типа. Для того, чтобы операции с содержимым были возможны, компилятору необходимо знать его тип. Указатель сдвигается вперед (при прибавлении целого числа N) или назад (при вычитании целого числа N) на соответствующее количество переменных того типа, на который указывает указатель. Значение указателя всегда изменяется на число байтов, равное N*sizeof(*имя_указателя) или N*sizeof(тип_указателя).

Указатели одного типа можно вычитать друг из друга. Разность указателей показывает, сколько переменных соответствующего типа может разместиться между этими указателями.

Складывать два указателя в языке С(С)++ запрещено.

Над указателями можно выполнять следующие операции:

  • взятие адреса & &ptra;

  • разыменование * *ptra;

  • определение размера указателя sizeof(ptra);

  • преобразование типов (char*)ptra;

  • присваивание ptra=&a;

  • сложение и вычитание целых чисел ptra+=3; ptra–=2;

  • инкремент, декремент ptra++; ptra–-;

  • вычитание указателей int n=ptra-ptrb;

  • операции отношения == != > >= < <=  ptra>ptrb;.

Рассмотрим некоторые операции над указателями.

Пример .

int a=1,b=7,c;

int *pa=&a, *pb=&b, *pc=&c;

printf("pa=%p pb=%p pc=%p \n",pa,pb,pc);

printf("pa-pb=%d pa-pc=%d ",pa-pb, pa-pc);

Результат:

pa=8B04:0FFE pb=8B04:0FFC bc=8B04:0FFA

pa-pb=1 pa-pc=2

При определении указатель и переменная, на которую он указывает, могут быть определены как

Связь указателей с массивами

Существует связь между массивами и указателями. При определении массива ему выделяется память для всех элементов массива. Но имя массива воспринимается как константный указатель того типа, к которому отнесены элементы массива. Имя массива – это указатель-константа, значением которого служит адрес нулевого элемента массива.

Пример.

int m[]={1,2,3,4};

printf("*m=%d *(m+1)=%d\n",*m,*(m+1));// 1 2

for(int i=8;i<11;i++)

printf("%c",*(str+i));// C++

Если применить операцию sizeof(имя_массива), то результатом будет объем памяти в байтах, выделенный под весь массив. Если применить операцию взять адрес (&имя_массива), то получим адрес начального элемента массива. То есть имя массива ‑ это весь массив, а также адрес нулевого элемента.

Доступ к элементам массива осуществляется с использованием индекса, который является смещением от начала массива, arr[0], arr[1], arr[2]…, а также путем разыменования указателя *arr,*(arr+1),*(arr+2).

При обработке массива для компилятора без разницы, как записано обращение к элементам массива. Например:

int mas[4]={9,8,7,6};

int *pmas=mas;

Так к последнему элементу массива mas можно обратиться следующими способами: mas[3],*(mas+3),*(3+mas), 3[mas]. Эти записи эквивалентны. Можно также использовать указатель pmas: pmas[3],*(pmas+3),*(3+pmas), 3[pmas]. Все эти записи позволяют обратиться к элементу массива: 2[mas].

Динамическим называется массив, размер которого может меняться во время исполнения программы. Для изменения размера динамического массива язык программирования, поддерживающий такие массивы, должен предоставлять встроенную функцию или оператор. Динамические массивы дают возможность более гибкой работы с данными, так как позволяют не прогнозировать хранимые объёмы данных, а регулировать размер массива в соответствии с реально необходимыми объёмами. Обычные, не динамические массивы называют ещё статическими.

[править]Пример объявления динамического массива на языках C/C++

Одномерный динамический массив:

Создаем массив с 10-ю элементами типа int:

int *mas = new int[10];

Получить доступ к значению каждого элемента можно по индексу (порядковый номер):

mas[0] = 2; // присвоили значение 2 нулевому элементу массива mas

mas[1] = 7; // присвоили значение 7 первому элементу массива mas

//... и т.д.

Следовательно, если брать такой подход, то вам понадобится около десяти строк кода, чтобы проинициализировать весь массив. Для того, чтобы этого избежать напишем тоже самое в цикле:

for(int i = 0; i < 10; i++){

cin>>mas[i]; // пользователь вводит значение каждого i-того элемента массива

}

После чего работаем с массивом. Также его можно вывести на экран:

for(int i = 0; i < 10; i++){

cout << mas[i] << endl;

}

Для освобождения из памяти одномерного динамического массива используем оператор delete:

delete []mas;

В случае, если массиву память будет выделена при помощи malloc, то для освобождения такого массива из памяти следует использовать функцию

free(mas);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]