Программирование на C++
Использование указателей и ссылок в программировании на C++. Определение, объявление и перегрузка функций. Работа с многомерными массивами. Рекурсивное описание алгоритмов обработки и их программная реализация. Структуры, объединения и поля битов.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | отчет по практике |
Язык | русский |
Дата добавления | 14.03.2014 |
Размер файла | 291,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Министерство образования и науки Украины
Донецкий политехнический техникум
ОТЧЕТ
по учебной практике
Выполнил студент гр. ПЗ-10-1
Кулешов Дмитрий Александрович
________________________________
(подпись)
Проверил:
_____________________________________
(ф.и.о)
___________ _________________________
(оценка) (подпись)
г. Донецк, 2013
Оглавление
1. УКАЗАТЕЛИ. ССЫЛКИ
1.1 Теоретическая часть
1.2 Практическая часть
Задание 1.2.1
Задание 1.2.2
Задание 1.2.3
Задание 1.2.4
Задание 1.2.5
Задание 1.2.6
Задание 1.2.7
Задание 1.2.8
Задание 1.2.9
Задание 1.2.10
Задание 1.2.11
Задание 1.2.12
Задание 1.2.13
Задание 1.2.14
Задание 1.2.15
1.3 Индивидуальное задание
2. ФУНКЦИИ
2.1 Теоретическая часть
2.2 Практическая часть
Задание 2.2.1
Задание 2.2.2
Задание 2.2.3
Задание 2.2.4
Задание 2.2.5
Задание 2.2.6
Задание 2.2.7 программирование алгоритм функция
Задание 2.2.8
Задание 2.2.9
Задание 2.2.10
Задание 2.2.11
Задание 2.2.12
Задание 2.2.13
2.3 Индивидуальное задание
3. ФУНКЦИИ И МАССИВЫ
3.1. Теоретическая часть
3.2. Практическая часть
Задание 3.2.1
Задание 3.2.2
Задание 3.2.3
Задание 3.2.4
Задание 3.2.5
Задание 3.2.6
Задание 3.2.7
Задание 3.2.8
Задание 3.2.9
Задание 3.2.9
Задание 3.2.9
3.3 Индивидуальное задание
4. ДВУМЕРНЫЕ МАССИВЫ
4.4 Теоретическая часть
4.5 Практическая часть
Задание 4.2.1
Задание 4.2.2
Задание 4.2.3
Задание 4.2.4
Задание 4.2.5
Задание 4.2.6
Задание 4.2.7
Задание 4.2.8
Задание 4.2.9
Задание 4.2.10
Задание 4.2.11
Задание 4.2.12
Задание 4.2.13
Задание 4.2.14
Задание 4.2.15
Задание 4.2.16
Задание 4.2.17
Задание 4.2.18
5. РЕКУРСИВНЫЕ ФУНЦИИ
5.1 Теоретическая часть
5.2 Практическая часть
Задание 5.2.1
Задание 5.2.2
Задание 5.2.3
Задание 5.2.4
Задание 5.2.5
Задание 5.2.6
Задание 5.2.7
Задание 5.2.8
Задание 5.2.9
Задание 5.2.10
Задание 5.2.11
Задание 5.2.12
Задание 5.2.13
6. СТРОКИ
6.1 Теоретическая часть
6.2 Практическая часть
Задание 6.2.1
Задание 6.2.2
Задание 6.2.3
Задание 6.2.4
Задание 6.2.5
Задание 6.2.6
Задание 6.2.7
Задание 6.2.8
Задание 6.2.9
Задание 6.2.10
Задание 6.2.11
Задание 6.2.12
Задание 6.2.13
Задание 6.2.14
Задание 6.2.15
Задание 6.2.16
Задание 6.2.17
Задание 6.2.18
Задание 6.2.19
Задание 6.2.20
Задание 6.2.21
Задание 6.2.22
Задание 6.2.23
Задание 6.2.24
Задание 6.2.25
Задание 6.2.26
7. СТРУКТУРЫ. ОБЪЕДИНЕНИЯ. ПОЛЯ БИТОВ В СТРУКТУРАХ
Задание 7.2.1
Задание 7.2.2
Задание 7.2.3
Задание 7.2.4
Задание 7.2.5
Задание 7.2.6
Задание 7.2.7
8. БАЗОВЫЕ АЛГОРИТМЫ РАБОТЫ С МАССИВАМИ
Задание 8.2.1
Задание 8.2.2
Задание 8.2.3
Задание 8.2.4
Задание 8.2.5
Задание 8.2.6
Задание 8.2.7
Задание 8.2.8
Задание 8.2.9
Задание 8.2.10
9. ИСПОЛЬЗОВАНИЕ ГРАФИЧЕСКИХ СРЕДСТВ
Задание 9.1.1
Задание 9.1.2
1 УКАЗАТЕЛИ. ССЫЛКИ
1.1 Теоретическая часть
В С++, помимо доступа к переменной по ее имени, существует возможность использования механизма указателей. Различают указатели-переменные и указатели-константы.
Указатель-переменная (указатель) - это переменная, предназначенная для хранения адреса. Указатель занимает 4 байта памяти. Значением переменной-указателя является адрес данного, адрес участка памяти, выделенного для объекта конкретного типа. Указатель не является самостоятельным типом, он всегда связан с каким-либо другим конкретным типом. В определении указателя всегда присутствует обозначение соответствующего ему типа.
Для доступа к объекту через указатели в С++ определена операция *(операция разыменования, т.е. обращения к содержимому участка памяти, адрес которого хранится в указателе). Чтобы операция разыменования выполнялась правильно, указатель должен иметь некоторое значение. Получить его он может в результате инициализации или присваивания.
Указатели делятся на две категории: указатели на объекты и указатели на функции. Рассмотрим сначала указатели объектов (на объекты).
Определение переменной-указателя на некоторый объект: в совокупности имя типа и символ * перед именем воспринимаются как обозначение особого типа данных «указатель на объект данного типа»
Стиль определения указателей:
- каждый указатель определяется на отдельной строке; символ `*' пишется сразу (без промежуточных пробелов) за названием типа объектов, которые определяемый указатель может адресовать: int* p;
- если в строке определяется более одного объекта, то символ `*' необходимо записывать непосредственно перед определяемым указателем: int *p.
Указатель типа void * является особым типом указателя. Ключевое слово void говорит об отсутствии данных о размере объекта в памяти. Указателю на void можно присвоить значение указателя любого типа, а также сравнивать его с любыми указателями. Но компилятору для корректной интерпретации ссылки на память через указатель нужна информация о числе байтов, участвующих в операции. Поэтому во всех случаях использования указателя, описанного как void*, необходимо выполнить операцию явного приведения типа указателя, т.е. преобразовать указатель к конкретному типу явным образом.
Инициализация переменной-указателя
Присвоение значения указателю - это возможность избежать ошибки! Существует несколько способов присвоить значение переменной-указателю:
- инициализация указателя адресом переменной, определенной ранее
- инициализация указателя значением другого указателя, ранее проинициализированного
- определение указателя вне любой функции с предписанием static
- инициализация указателя явным адресом памяти с последующим приведением типа
- инициализация указателя именем массива или присвоение ему имени функции, которые трактуются как адреса-константы
- инициализация указателя нулевым значением
- инициализация указателя адресом участка динамической памяти
Операции над указателями
Для указателей-переменных разрешены операции:
- доступа по указателю (разыменования или косвенного обращения к объекту (*)),
- присваивания,
- приведение типов,
- сложение с константой,
- инкремента или декремента,
- вычитание двух указателей,
- сравнение указателей (одного типа),
- получения адреса (&).
Ссылка, в отличие от указателя, не занимает дополнительного пространства в памяти и является просто другим именем (псевдонимом) для переменной. Ссылка представляет собой синоним имени переменной, указанной при ее инициализации, т.е. объявленной ранее. Имя ссылки может использоваться вместо имени переменной. Ссылку можно рассматривать как указатель, который всегда разыменовывается. В отличие от указателя ссылка не может быть изменена, чтобы представлять другую переменную. Но на данную переменную может быть объявлено несколько ссылок.
Формат объявления ссылки:
Базовый_тип &Имя_Ссылки = Имя_Переменной;
Например:
int kol;
int& pal = kol; //ссылка pal - альтернативное имя для ko
Ссылка на переменную не может инициализироваться константой, компилятор выдаст ошибку, так как предполагает, что последует изменение величин, на которые ссылаются jj и jjj, и на всякий случай устраняет искушение. Иначе говоря, константность - свойство переменной, а не данных, поэтому неконстантная переменная не может ссылаться на константную величину.
Правила:
- Ссылка явно инициализируется при ее описании, кроме случаев, когда она является параметром функции, описана как extern или ссылается на поле данных класса.
- Ссылке после инициализации не может быть присвоена другая переменная, но на данную переменную может быть объявлено несколько ссылок.
- Тип ссылки должен совпадать с типом величины, на которую она ссылается.
- Не разрешается определять указатели на ссылки, создавать массивы ссылок и ссылки на ссылки.
- Указатель можно инициализировать адресом ссылки.
- Ссылки применяются чаще всего в качестве параметров функций и типов значений, возвращаемых функциями.
1.2 Практическая часть
Задание 1.2.1
Операция & позволяет получить адрес переменной:
//вывод на экран адресов переменных
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int var1 = 11;
int var2 = 22;
int var3 = 33;
cout << &var1 << endl
<< &var2 << endl
<< &var3 << endl;
_getch();
return 0;
Задание 1.2.2
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int ivar1, ivar2;
int* iptr;
iptr = &ivar1;
*iptr = 37;
ivar2 = *iptr;
cout <<ivar2 << endl;
_getch();
return 0;}
Задание 1.2.3
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{int ivar1 = 11;
int ivar2 = 22;
cout << &ivar1 << endl ; //вывод на экран значения адреса переменной ivar1
cout << &ivar2 << endl ; //вывод на экран значения адреса переменной ivar2
int *iptr = &ivar1; //инициализация указателя на int iptr адресом ivar1
cout << iptr << endl; //вывод содержимого iptr (значения адреса)
cout << *iptr << endl; //вывод разыменованного содержимого iptr //(значения переменной ivar1=11)
iptr = &ivar2; //указателю iptr присваивается адрес ivar2
cout << iptr << endl; //вывод нового содержимого iptr (значения адреса)
cout << *iptr << endl; //вывод разыменованного содержимого iptr // (значения переменной ivar2=22)
_getch();
return 0;}
Присваивание и приведение типа
Задание 1.2.4
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int intvar;
float flovar;
int* ptrint; //определение указателя на int
float* ptrflo; // определение указателя на float
void* ptrvoid; // определение указателя на void
ptrint = &intvar; //ok, int* to int*
//ptrint = &flovar; //error, float* to int*
//ptrflo = &intvar; //error, int* to float*
ptrflo = &flovar; //ok, float* to float*
ptrvoid = &intvar; //ok, int* to void*
ptrvoid = &flovar; //ok, float* to void*
_getch();
return 0;}
Задание 1.2.5
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int intvar=5; float flovar=5.0f; double dvar=5.0;
int* ptrint =NULL; //определение и инициализация указателя на объект типа int
float* ptrflo =NULL; // определение и инициализация указателя на объект типа float
double* ptrd =NULL; // определение и инициализация указателя на объект типа double
void* ptrvoid =NULL; // определение и инициализация указателя на void
//Операция присваивания выполнена верно:
ptrint = &intvar; //присваивание указателю на объект типа int адреса объекта типа int
ptrflo = &flovar; //присваивание указателю на объект типа float адреса объекта типа float
ptrd = &dvar; // присваивание указателю на объект типа double адреса объекта типа double
ptrvoid = &intvar; //присваивание указателю на void адреса объекта типа int
ptrvoid = &flovar; // присваивание указателю на void адреса объекта типа float
ptrvoid = &dvar; // присваивание указателю на void адреса объекта типа double
ptrvoid = ptrint; // присваивание указателю на void указателя на объект типа int
ptrvoid = ptrflo; // присваивание указателю на void указателя на объект типа float
ptrvoid = ptrd; // присваивание указателю на void указателя на объект типа double
ptrint = reinterpret_cast <int*> (ptrvoid);
ptrflo = reinterpret_cast <float*> (ptrvoid);
ptrd = reinterpret_cast <double*> (ptrvoid);
ptrvoid = reinterpret_cast <void*> (ptrint);
ptrvoid = reinterpret_cast <void*> (ptrflo);
ptrvoid = reinterpret_cast <void*> (ptrd);
ptrint = reinterpret_cast <int*> (&dvar);
ptrflo = reinterpret_cast <float*> (&intvar);
ptrint = reinterpret_cast <int*> (&flovar);
_getch();
return 0;}
Задание 1.2.6
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{ int intvar=5;
double dvar=2.0;
int *ptrint = &intvar; double *ptrd=NULL;
ptrd = reinterpret_cast <double*> (&intvar); //явное приведение адреса переменной типа int к указателю на double
_getch();
return 0;}
Задание 1.2.7
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{unsigned long block = 0xffeeddccL; // переменная block занимает 4 байта
void *ptr = █ //указатель на переменную block
unsigned char ch;
unsigned short two_bytes;
unsigned long four_bytes; //адрес переменной есть адрес ее младшего байта
ch = *( reinterpret_cast <unsigned char*>(ptr));
//приведение указателя ptr к типу «указатель на unsigned char» и взятие значения
printf ("%x", ch); // cc (1 байт)
two_bytes = *( reinterpret_cast <unsigned short *>(ptr));
//приведение указателя к типу «указатель на unsigned short»
// и взятие значения (2 байта)
printf ("%x", two_bytes); // ddcc
four_bytes = *( reinterpret_cast <unsigned long *>(ptr));
//приведение указателя к типу «указатель на unsigned long» и
// взятие значения (4 байта)
printf ("%x", four_bytes); // ffeeddcc
_getch();
return 0;}
Задание 1.2.8
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int i=5, j=6, *pi =&i, *pj =&j;
*pi=*pj;
cout << pi << endl; // 0012FF60
cout << pj << endl; // 0012FF54
++pi=&j;
cout << pi << endl; // 0012FF54
cout << pj << endl; // 0012FF54
_getch();
return 0;}
int main ()
{int i=5, j=6, *pi =&i, *pj =&j;
*pi=*pj;
cout << pi << endl;
cout << pj << endl;
//pi++=&j; error C2106: '=' : left operand must be l-value
cout << pi << endl;
cout << pj << endl;
_getch();
return 0;}
Задание 1.2.9
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int i=5, j=6, *pi =&i, *pj =&j;
*pi=*pj;
cout << pi << endl; // 0012FF60
cout << pj << endl; // 0012FF54
++pi=&j;
cout << pi << endl; // 0012FF54
cout << pj << endl; // 0012FF54
_getch();
return 0;}
int main ()
{int i=5, j=6, *pi =&i, *pj =&j;
*pi=*pj;
cout << pi << endl;
cout << pj << endl;
//pi++=&j; error C2106: '=' : left operand must be l-value
cout << pi << endl;
cout << pj << endl;
_getch();
return 0;}
Задание 1.2.10
Текст программы:
#include "stdafx.h"
#include <cstdlib>
#include <conio.h>
int _tmain(int argc, _TCHAR* argv[])
{int *xiptr, *wiptr, yi, zi; //память под указатель выделяется на этапе компиляции
xiptr=(int *) malloc (sizeof(int)); //память для инициализации указателя
//выделяется в процессе выполнения программы
//еще лучше, вдруг в куче нет места:
// if ( (xiptr=( reinterpret_cast <int *>( malloc (sizeof (int)) ) ) !=0){…..}
*xiptr=16;
yi=-15;
wiptr=&yi;
printf ("\nsizeof(xiptr) = %d ", sizeof(xiptr));
printf ("xiptr = %p ", xiptr);
printf ("*xiptr = %d ", *xiptr);
printf ("\n&yi = %p", &yi);
printf ("\n&zi = %p", &zi);
printf ("\n*wiptr = %d\n", *wiptr);
_getch();
return 0;}
Задание 1.2.11
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int var1=5, *pvar1=&var1;
int var2=6;
const int cvar1 = 1; // cvar1 - целая константа
// pcvar1, pcvar11 - указатели на константу
const int *pcvar1 = &cvar1; // const запрещает изменение значения *pcvar1
const int *pcvar11 = &var2; // const запрещает изменение значения *pcvar11
cout << *pvar1 << " " << *pcvar1 << " " << *pcvar11 << endl; // 5 1 6
// *pcvar11=*pvar1; // l-value specifies const object
// *pcvar1=*pcvar11; // l-value specifies const object
pcvar11 = pcvar1; // OK!!! изменение самого указателя разрешено
pcvar1 = pvar1; // OK!!! изменение самого указателя разрешено
cout << *pvar1 << " " << *pcvar1 << " " << *pcvar11 << endl; // 5 5 1 return 0;}
Задание 1.2.12
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int var1=5, *pvar1=&var1;
int var2=6;
const int cvar1 = 1; // cvar1 - целая константа
const int *pcvar1 = &cvar1; // pcvar1 - указатель на константу
// cp1 - константный указатель
int *const cp1 = &var1; // const запрещает изменение значения указателя
cout << *cp1 << endl; // 5
// cp1 = pvar1; // l-value specifies const object
*cp1 = var2; //OK!!! изменение содержимого по указателю разрешено
cout << *cp1 << endl; // 6
*cp1 = *pcvar1; // OK!!! изменение содержимого по указателю разрешено
cout << *cp1 << endl; // 1
// int *const cp2 = &cvar1; // cannot convert from 'const int *' to 'int *const `
// cp1 = pcvar1; // cannot convert from 'const int *' to 'int *const `
// cp1 = reinterpret_cast <int *const> (pcvar1);
//'reinterpret_cast' : cannot convert from 'const int *' to 'int *const ' return 0;}
Задание 1.2.13
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int var1=5, *pvar1=&var1;
int var2=6;
const int cvar1 = 1; // cvar1 - целая константа
// сpc1, сpc2 - константные указатели на константу
// модификатор const запрещает изменение значения
const int *const cpc1 = &var1; // и указателя, и содержимого *cpc1, *cpc2
const int *const cpc2 = &cvar1;
cout << *cpc1 << endl; // 5 1
// cpc1 = pvar1; // l-value specifies const object
// *cpc1 = 8; // l-value specifies const object return 0;}
Задание 1.2.14
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int ivar1=5;
int *pivar1 = &ivar1, **pivar2=&pivar1; //определение указателей
cout << *pivar1<< endl; // 5, вывод значения по указателю
cout << *pivar2 <<endl; //00AB0100
cout << **pivar2 <<endl; //5
int ivar1=5;
int *pivar1 = &ivar1;
int **pivar2 = &pivar1;
int ***pivar3 = &pivar2;
cout << ivar1 << " " << &ivar1 << endl;
cout << *pivar1 << " " << &pivar1 << endl;
cout << **pivar2 << " " << &pivar2 << endl;
cout << ***pivar3 << " " << &pivar3 << endl;
cout << pivar1 << " " << *pivar1 << endl; // 0x0012FF7C 5
cout << pivar2 << " " << *pivar2 << " " << **pivar2 << endl;
// 0x0012FF78 0x0012FF7C 5
cout << pivar3 << " " << *pivar3 << " " << **pivar3 << " " << ***pivar3 << endl;
return 0;}
Задание 1.2.15
Текст программы:
#include <stdafx.h>
#include <iostream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{int i = 0;
int &rint = i; // ссылка rint синоним переменной i
int *pint = &i; // указатель pint проинициализирован адресом i
rint +=10; //ссылка не требует разыменования
*pint +=10; // для указателя требуется разыменование
int &rr = i; //вторая ссылка - rr - синоним переменной i
int *p = &rr; //еще один указатель на i, но через ссылку!!!;
_getch();
return 0;}
1.3 Индивидуальное задание
Вариант 1
Для х изменяющегося от a до b с шагом (b-a)/k, где (k=10), вычислить функцию f(x), используя ее разложение в степенной ряд в двух случаях:
а) для заданного n;
б) для заданной точности (=0.0001).
Для сравнения найти точное значение функции
Рисунок 1.16 - Условие задания
Текст программы:
#include <iostream.h>
#include <math.h>
#include <cstdlib>
#define A 0.1
#define B 0.8
#define E 0.0001
int main (int argc, char*argv[])
{float x,k=(B-A)/10,sn=0,se=0,t,y;
int i,j,n=50;
for (x=A;x<=B;x+=k)
{sn=x;se=x;
for (i=1;i<=n;i++)
{sn+=pow(cos(n*x/4),2)/(n*n-1);}
j=1;
do
{t=cos*2*n*x/4*pow(n,2)-1;
j++;se+=t;}
while (t>E);
y=1/2-pi/4*abs(sin(x));
printf ("x%.2f SN=%f SE=%f Y=%f\n",x,sn,se,y);}}
2. ФУНКЦИИ
2.1 Теоретическая часть
Функции в С++
Любая программа в С++ состоит из функций, из которых одна должна иметь имя main (с нее начинается выполнение программы). Функция - это именованная последовательность операторов, выполняющая какое-либо законченное действие. Она может принимать параметры и возвращать значение и описывается замкнутой программной конструкцией, имеющей заголовок и тело.
Любая функция должна быть объявлена и определена.
Объявление функции (прототип) задает ее имя, тип возвращаемого значения, список передаваемых параметров, необязательный спецификатор памяти (extern, static) и завершается символом «точка с запятой».
Определение функции содержит заголовок функции и ее тело, представляющее собой программный код, выполняемый при вызове функции (последовательность операторов и описаний в фигурных скобках):
[класс] тип_возвр_знач имя ([список параметров ])
{тело функции}
Существенное различие между определением и объявлением функции: определение содержит собственно тело функции. Определение всегда одно, а объявлений может быть несколько. Объявление функции должно находиться в тексте раньше ее вызова для того, чтобы компилятор мог осуществить проверку правильности вызова.
Три способа объявления функции:
- Определение функции дать перед main(), тогда объявление может отсутствовать.
- Записать прототип функции в файл, в котором она используется.
- Записать прототип функции в заголовочный файл, и включить его директивой #include в программу.
Список параметров определяет величины, которые требуется передать в функцию при её вызове. Элементы списка параметров разделяются запятыми. Для каждого параметра указывается его тип и имя (в объявлении (прототипе) имена можно опускать: они нужны не транслятору, а человеку, для улучшения читабельности программ). При каждом новом обращении к функции в нее могут передаваться значения разных переменных. Параметры, перечисленные в заголовке определения функции, называются формальными параметрами, или просто параметрами, а записанные в операторе вызова функции - фактическими параметрами или аргументами.
Сигнатура функции - это ее заголовок за вычетом типа функции.
В С++ (при С-порядке передачи аргументов в функцию) копии аргументов располагаются в стеке в следующем порядке: последний аргумент, предпоследний аргумент и т.д.
Вызов функции может находиться в любом месте программы, где по синтаксису допустимо выражение того типа, который возвращает функция.
Для вызова функции в общем случае необходимо указать ее имя, за которым в круглых скобках через запятую перечислить имена передаваемых аргументов (фактических параметров). Если функция func объявлена без параметров (с пустым списком формальных параметров), то ее вызовом является имя с пустыми скобками: func(); (это предполагает, как правило, использование глобальных переменных).
Если тип возвращаемого функцией func значения есть void, то ее вызов имеет вид func(x); если тип возвращаемого функцией значения не void, то она может входить в состав выражений или, в частном случае, располагаться в правой части оператора присваивания: A= func(x);
Вызов функции с одним возвращаемым значением можно записать:
- в операторе присваивания, например: sd =SUMDIG(1234);
- непосредственно в операторе if, не присваивая предварительно значение функции переменной (if (SUMDIG(a)>10)…), где a - переменная целого типа;
- в операторе while, например, while(SUMDIG(a*a)!=num) или while (SUMDIG(a*a)-num)… и в других операторах;
- в вызове другой функции в качестве фактического параметра, например, LINE2(SUMDIG(a), 5, `.');
Механизм возврата из функции в вызвавшую ее функцию реализуется оператором return выражение. Тип возвращаемого функцией значения может быть любым, кроме массива и функции (но может быть указателем на массив или функцию). Если функция не должна возвращать значения, указывается тип void.
Выражение, указанное после return, неявно преобразуется к типу возвращаемого функцией значения и передается в точку вызова функции. Как частный случай выражения, можно возвращать константу или значение одной переменной. Оператор может быть единственным в функции:
float MyFunc1(float x, float y)
{return x+y;}
Функция может содержать несколько операторов return (это определяется алгоритмом) и такой оператор не обязательно должен быть в конце функции. Но выполняется всегда один из операторов.
Оператор return прекращает работу любой функции, в том числе и типа void, поэтому он не обязательно должен иметь возвращаемое значение. Если функция описана как void, выражение в return не указывается.
Если из функции необходимо вернуть более одного значения, то используются дополнительные параметры и их передача по указателю или по ссылке (об этом поговорим чуть позже).
Нельзя возвращать из функции указатель на локальную переменную, поскольку память, выделенная локальным переменным при входе в функцию, освобождается после возврата из нее.
Стандартные функции
Стандартные библиотечные модули системы С++ содержат большой набор библиотечных функций. Их использование является мощным средством расширения языка и возможностей системы. Библиотечные функции хранятся в скомпилированном виде и подключаются к программе на этапе компоновки. В программах на С++ могут использоваться функции, унаследованные от библиотеки С.
Функции библиотеки можно разбить на группы по их назначению: ввод/вывод, обработка строк, математические функции, работа с динамической памятью, поиск и сортировка и т.д.
Ввод/вывод в С++ реализуется либо с помощью функций, унаследованных от библиотеки С (заголовочный файл <stdio.h> или <cstdio>), либо с помощью потоков С++.
Математические функции мы рассматривали в рамках лабораторной работы 1.
В С++ есть функции стандартной библиотеки для работы с символами (заголовочные файлы <ctype.h> или <cctype>) и для работы со строками: функции, унаследованные из библиотеки С (заголовочные файлы <string.h> или <cstring>, <stdlib.h> или <cstdlib>), и библиотечный класс string.
Механизм вызова функций и передачи параметров
Механизм параметров является основным способом обмена информацией между вызываемой и вызывающей функциями и включает:
- выделение вызываемой функции локальной памяти (память процесса выполнения ее вызова);
- вычисление и запоминание в локальной памяти точки возврата в вызывающую функцию;
- вычисление значений для аргументов, соответствующих параметрам, передаваемым по значению и по указателю, и ссылок на память для аргументов, соответствующих параметрам, передаваемым по ссылке;
- подстановку аргументов (в стеке выделяется память под формальные параметры функции в соответствии с их типом, и каждому из них присваивается значение соответствующего аргумента); при этом проверяется соответствие типов и при несоответствии выдается диагностическое сообщение;
- выполнение операторов тела функции и запоминание в локальной памяти значения, возвращаемого вызовом функции;
- копирование из локальной памяти в память вызывающей функции (в переменную, отведенную для этих целей) значения, возвращаемого вызовом функции; локальная память функции делается недоступной, освобождается для выполнения следующих вызовов;
- продолжение выполнения вызывающей функции с точки возврата.
2.2 Практическая часть
Задание 2.2.1
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
void starline();
int _tmain(int argc, _TCHAR* argv[])
{cout <<"Data type Range" << endl;
starline();
cout << "char -128 to 127" <<endl
<< "short -32?768 to 32,767" << endl
<< "int System dependent" << endl
<< "long -2,147,483,648, to 2,147,483,647" <<endl;
starline();
_getch();
return 0;}
void starline()
{for (int j=0; j<45; j++)
cout << '*';
cout << endl;}
Задание 2.2.2
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
void repchar (char, int);
int _tmain(int argc, _TCHAR* argv[])
{repchar ('-', 43);
cout << "Data type Range" << endl;
repchar ('=', 23);
cout << "char -128 to 127" << endl
<< "short -32,768 to 32,767" << endl
<< "int System dependent" << endl
<< "double -2,147,483,648 to 2,147,483,647" << endl;
repchar ('-', 43);
_getch();
return 0;}
void repchar (char ch, int n)
{for (int j=0; j<n; j++)
cout << ch;
cout << endl;}
Задание 2.2.3
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
void starline()
{for (int j=0; j<45; j++)
cout <<'*';
cout <<endl;}
int _tmain(int argc, _TCHAR* argv[])
{starline();
cout << "Data type Range" <<endl;
starline();
cout << "char -128 to 127" << endl
<< "short -32,768 to 32,767" << endl
<< "int System dependent" << endl
<< "double -2,147,483,648 to 2,147,483,647" << endl;
starline();
_getch();
return 0;}
Задание 2.2.4
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
char ch = 'a';
void getachar();
void getachar();
int _tmain(int argc, _TCHAR* argv[])
{getachar();
while (ch != '\r' )
{getachar();
getachar();}
cout << endl;
_getch();
return 0;}
void getachar()
{ch = _getch();
return;}
void putachar()
{_putch (ch);
_putch ('\r');
_putch ('\n');
return;}
Задание 2.2.5
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
float getavg(float);
int _tmain(int argc, _TCHAR* argv[])
{float data=1, avg;
while (data !=0)
{cout << "Enter a number: ";
cin >> data;
avg = getavg (data);
cout << avg << endl;}
_getch();
return 0;}
float getavg (float newdata)
{static float total = 0;
static int count = 0;
count++;
total += newdata;
return total / count;}
Задание 2.2.6
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
void changePtr (double *a, double *b)
{double c=*a;
*a=*b;
*b=c;}
void changeRef (double& x, double& y)
{double z=x;
x=y;
y=z;}
void main()
{double d=1.23;
double e=4.56;
changePtr (&d, &e);
cout << " \nd= " << d << " \t\te=" << e ;
changeRef (d, e);
cout << " \nd= " << d << " \t\te=" << e ;
cout << endl;
_getch();
return;}
Задание 2.2.7
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
int x;
int& setx();
int main()
{setx() = 92;
cout << "x=" << x << endl;
_getch();
return 0;}
int& setx()
{return x;}
Задание 2.2.8
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
void aFunc(int&, const int&); //прототип функции; параметр, передаваемый
// с модификатором const, разрешено только «считывать»
int main()
{int alpha = 7;
int beta = 11;
aFunc(alpha, beta);
cout << alpha << " " << beta << endl;
_getch();
return 0;}
//--------------------------------------------------------------
void aFunc(int& a, const int& b) //определение функции
{a = 107;}
Задание 2.2.9
Текст программы:
#include "stdafx.h"
#include <сstdlib> //для atexit()
#include <сtime> //для time(), сtime(), clock() и CLOCKS_PER_SEC
void adder (void); //прототип функции, объявленной для завершения программы
int _tmain(int argc, _TCHAR* argv[])
{ atexit(adder); //вызов функции atexit() регистрирует adder() в качестве
// функции, завершающей работу программы
//…..операторы тела функции main
return 0;}
void adder (void) //определение функции завершения программы, которая
//не должна иметь параметров и возвращаемого значения
{ time_t t; //или long t;
//функция time () возвращает текущую дату в виде количества секунд
cout <<time(&t)<< endl;
//функция ctime () возвращает строку, в которую преобразует текущую дату
cout <<ctime(&t)<< endl;
//функция clock_t clock (void) возвращает время исполнения программы
//для перевода в секунды делим его на константу CLOCKS_PER_SEC
cout << clock()/CLOCKS_PER_SEC << endl; //время работы в сек
_getch();
return;}
Задание 2.2.10
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
inline double lbstokg (float pounds) // функция конвертирует фунты в килограммы
{return 0.453592 * pounds;}
//--------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{float lbs;
cout << "\n Enter your weight in pounds: ";
cin >> lbs;
cout << "Your weight in kilograms is " << lbstokg (lbs)<< endl;
_getch();
return 0;}
Задание 2.2.11
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
void repchar(char='*', int=45); //прототип функции с параметрами по умолчанию
int _tmain(int argc, _TCHAR* argv[])
{repchar(); //вызов функции с двумя аргументами по умолчанию
//печать 45 символов «звездочка»
repchar('='); //вызов функции с заданным первым аргументом
//печать 45 знаков «равно»
repchar('+', 30); //вызов функции с двумя заданными аргументами
//печать 30 знаков «плюс»
_getch();
return 0;}
//--------------------------------------------------------------
void repchar(char ch, int n)
{for(int j=0; j<n; j++)
cout << ch;
cout << endl;
return;}
Задание 2.2.12
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
void example (int,...);
int main(void)
{int var1=5, var2=6, var3=7, var4=8, var5=9;
example(2, var1); //вызов функции с двумя аргументами
example(3, var1, var2); //вызов функции с тремя аргументами
example(6, var1, var2, var3, var4, var5); //а теперь - шесть аргументов
_getch();
return 0;}
void example(int arg1, ...)
{int *ptr=&arg1; //установка указателя на первый аргумент
printf("\n peredano argumentov %d:\n", arg1);
for ( ; arg1; arg1--)
{printf("%d ", *ptr); ptr++;} //2 5 3 5 6 6 5 6 7 8 9
printf ("\n");}
Задание 2.2.13
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
void example (int,...);
int main(void)
{int var1=5, var2=6, var3=7, var4=8, var5=9;
example(var1, 0); //вызов функции с двумя аргументами
example(var1, var2, 0); //вызов функции с тремя аргументами
example(var1, var2, var3, var4, var5, 0); //а теперь - шесть аргументов
_getch();
return 0;}
void example(int arg1, ...)
{int number = 1;
int *ptr=&arg1; //установка указателя на первый аргумент
while(*ptr)
{number++;
printf("%d ", *ptr++);}
printf("\n peredano argumentov %d;\n", number-1);}
2.3 Индивидульное задание
Вариант 13
Сформировать одномерный массив целых чисел, используя датчик случайных чисел.
Распечатать полученный массив.
Удалить из массива все элементы совпадающие с его минимальным значением.
Добавить в начало массива 3 элемента с значением равным среднему арифметическому массива.
Распечатать полученный массив.
Текст программы:
#include "stdafx.h"
#include <clocale>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{ setlocale (LC_ALL,"Russian");
const int N = 10;
int massiv[N];
int srar = 0;
srand(time(NULL));
//Заполняем массив
for (int i = 0;i<N;i++)
{ massiv[i] = 1 + rand() % 10;
printf ("%d ",massiv[i]);}
//Удаляем минимальный элемент в массиве
int min = massiv[0];
for (int i = 0;i<N;i++)
{ if (min>massiv[i])
min = massiv[i];}
for (int i=0;i<N;i++)
{if(massiv[i]==min)
{for(int j=i+1;j<N;j++)
{massiv[j-1]=massiv[j];}
cout<<endl;
for(i=0;i<N;i++)
{cout <<massiv[i]<<" ";}
cout << "\nmin="<<min<<endl;
//Ищем среднее арифметическое
int sum = 0;
for (int i = 0;i<N;i++)
{sum +=massiv[i];}
srar = sum/N;
/*for (int i = 0;i<N;++i)
{if (massiv[i] == srar)
{for (int c=N, i = 0;i>3;i++)
{ massiv[c] = massiv [i];
c++;}}}
cout<<massiv[c];*/
cout<<"Среднее арифметическое: "<<srar<<"\n";
system("pause");
return 0;}}}
3. ФУНКЦИИ И МАССИВЫ
3.1 Теоретическая часть
Перегрузка функций
Часто необходимо, чтобы функции реализовывали один и тот же алгоритм для различных типов данных. При этом естественное требование - это наличие одного и того же имени для таких функций.
В С все имена функций должны быть уникальны в одном проекте. Это неудобно при работе с функциями, выполняющими одинаковые или похожие действия с разными типами данных (классический пример - стандартные функции abs(), labs(), fabs(), которые возвращают абсолютное значение, соответственно, целого, длинного целого и вещественного типов).
В С++ с одним и тем же именем можно определить несколько функций, отличающихся типами параметров и реже их количеством (сделать перегрузку функций).
Две функции называются перегруженными, если они имеют одинаковое имя, объявлены в одной и той же области видимости, но имеют разные списки формальных параметров (разные сигнатуры).
Именно сигнатуру транслятор использует, когда отыскивает среди перегруженных функций подходящую. И поэтому С++ требует, чтобы сигнатуры всех функций были разными. Свои внутренние («для служебного пользования») имена функций транслятор строит именно на основе сигнатур.
Если тип возвращаемого значения и списки параметров в объявлениях двух функций одинаковы, то второе объявление считается повторным (имена параметров при сравнении объявлений во внимание не принимаются).
Разрешение перегрузки
С++ при перегрузке не требует точного соответствия сигнатуры вызываемой функции сигнатуре одной из имеющихся функций. Если точно соответствующей перегруженной функции нет, он в состоянии подобрать наиболее подходящую из набора. Больше всего транслятор любит точное совпадение сигнатур, потом пытается подобрать сигнатуры с наиболее близкими и достаточными по размеру типами (например, float в вызове может соответствовать типу double в сигнатуре, но не наоборот), а некоторые варианты (например, замену char на char*) вообще не рассматривает.
Разрешением перегрузки функции называется процесс выбора той функции из множества перегруженных, которую следует вызвать. Этот процесс основывается на указанных при вызове аргументах.
Процесс разрешения перегрузки функций состоит из трех шагов:
1. Установить множество функций-кандидатов для разрешения данного вызова, а также свойства списка фактических аргументов.
2. Отобрать из множества кандидатов устоявшие функции - те, которые могут быть вызваны с данным списком фактических аргументов при учете их числа и типов.
3. Выбрать функцию, лучше всего соответствующую вызову, подвергнув ранжированию преобразования, которые необходимо применить к фактическим аргументам, чтобы привести их в соответствие с формальными параметрами устоявшей функции.
Рассмотрим шаги, выполняемые при разрешении перегрузки функции, более подробно:
- На первом шаге необходимо идентифицировать множество функций-кандидатов, т.е. перегруженных функций с тем же именем, что и вызванная, объявление которых видимо в точке вызова, и которые будут рассматриваться для данного вызова, а также свойства списка аргументов переданных функции (их количество и типы).
- На втором шаге среди множества функций-кандидатов отбираются устоявшие - такие, которые могут быть вызваны с данными аргументами, с учетом их количества и типов. Устоявшая функция либо имеет столько же формальных параметров, сколько фактических аргументов передано вызванной функции, либо больше, но тогда для каждого дополнительного параметра должно быть задано значение по умолчанию. Чтобы функция считалась устоявшей, для любого фактического аргумента, переданного при вызове, обязано существовать преобразование к типу формального параметра, указанного в объявлении.
Компилятор идентифицирует и ранжирует преобразования, которые следует применить к каждому фактическому аргументу вызванной функции для приведения его к типу соответствующего формального параметра любой из устоявших функций.
3.2 Практическая часть
Задание 3.2.1
Перегрузка функций с равным числом аргументов
Рассмотрим пример перегрузки функции циклического сдвига аргумента влево:
#include <iostream>
using namespace std;
short rotate(short i);
long rotate(long i);
int rotate(int i);
int main(){
short a = 0x8000;
int c = 0x8000;
long b = 8;
cout << rotate(a) << endl;
cout << rotate(b) << endl;
cout << rotate(c) << endl;
return 0;}//int
short rotate(short i){
short x;
if(i & 8000)
x = 1;
else
x = 0;
i = i << 1;
i += x;
return x;}
long rotate(long i){
long x;
if(i & 8000)
x = 1;
else
x = 0;
i = i << 1;
i += x;
return x;}
int rotate(int i){
int x;
if(i & 8000)
x = 1;
else
x = 0;
i = i << 1;
i += x;
return x;}
Задание 3.2.2
#include <iostream>
using namespace std;
int func(int a, int b){
return a+b;
float func(float a, float b){
return a-b;}
void main(){
int a = 25, b = 40;
float c = 2.5f, d = 6.15f;
cout << "\n summa = " << func(a,b) << endl;
cout << "\n raznost = " << func(c,d) << endl;}//main
Задание 3.2.3
#include <iostream>
#include <conio.h>
using namespace std;
int func (int a, intb); //прототип функции вычисления суммы
float func (float a, float b); //прототип функции вычисления разности
//--------------------------------------------------------------
int main ()
{int a=25, b=40;
float c=2.45f, d=6.15f;
cout << "\n summa=" << func (a,b); //вызов функции с аргументами целого типа
cout << "\n raznost=" << func (c,d); //вызов функции с аргументами типа float
_getch();
return 0;}
//--------------------------------------------------------------
int func(int a, intb) //определение функции вычисления суммы
{return (a+b);}
//--------------------------------------------------------------
float func(float a, float b) //определение функции вычисления разности
{return (a-b);}
Задание 3.2.4
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
template <class T>
T abs (T);
int main()
{int i1 = 5;
int i2 = -6;
long l1 = 70000L;
long l2 = -80000L;
double d1 = 9.95;
double d2 = -10.15;
cout << "\nabs (" << i1 << ")=" << abs<> (i1);
cout << "\nabs (" << i2 << ")=" << abs<int> (i2);
cout << "\nabs (" << l1 << ")=" << abs<>(l1);
cout << "\nabs (" << l2 << ")=" << abs<long>(l2);
cout << "\nabs (" << d1 << ")=" << abs<>(d1);
cout << "\nabs (" << d2 << ")=" << abs<double>(d2);
cout << endl;
_getch();
return 0;}
template <class T>
T abs (T n)
{return (n < 0) ? -n : n;}
Задание 3.2.5
Текст программы:
#include <iostream>
using namespace std;
float f(float i){
cout << "float f(float i)\n";
return i;}
double f(double i){
cout << "double f(double i)\n";
return i;}
void main(){
float x = 5.f;
double y = 10.09;
cout << f(x) << endl;
cout << f(y) << endl;}//main
Задание 3.2.6
Текст программы:
#include <iostream>
using namespace std;
float f(int i){
return i;}
double f(int i, int b = 1){
return i * b;}
void main(){
cout << f(11,6) << endl;}//main
Задание 3.2.7
Текст программы:
#include <iostream>
using namespace std;
template <class T>
T abs(T param){
return (param<0)? - param : param;}//abs
void main(){
int i1 = 5, i2 = -6;
long l1 = 70000L;
long l2 = -60000L;
double d1 = 9.95;
double d2 = 95.67;
cout << "\nabs(" << i1 << ")" << abs(i1) << endl;
cout << "\nabs(" << l1 << ")" << abs(l1) << endl;
cout << "\nabs(" << l2 << ")" << abs(l2) << endl;
cout << "\nabs(" << d1 << ")" << abs(d1) << endl;
cout << "\nabs(" << d2 << ")" << abs(d2) << endl;}//main
Задание 3.2.8
Текст программы:
#include <iostream>
using namespace std;
template <class T>
void swap(T* x, T* y){
T z = *x;
*x = *y;
*y = z;}//swap
void main(){
long k = 4, d = 8;
double a = 2.44, b = 66.3;
swap(&k,&d);
cout << k << " " << d << endl;
swap(&a,&b);
cout << a << " " << b << endl;}
Задание 3.2.9
Текст программы:
#include <iostream>
using namespace std;
template <class T>
T min3( T x, T y, T z){
T min = x;
if(y < min)
min = y;
if(z < min)
min = z;
return min;
}//min3
void main(){
int a = 2, b = 5, c = -5;
cout << min3(a*c,b,c) << endl;
cout << min3(0.38*a,0.5*b, 5.7) << endl;}
Задание 3.2.9
Текст программы:
#include <iostream>
using namespace std;
int N = 0;
emplate <class N>
N maxx(N x, N y){
N a = x;
cout << "\n N = " << ++ ::N << endl;
if(a<y)
a = y;
return a;
}//maxx
void main(){
int a = 12, b = 42;
maxx(a,b);
cout << a << "\t\t" << b << endl;
float z = 66.7f, f = 222.4f;
maxx(z,f);
cout << a << "\t\t" << b << endl;}//main
Задание 3.2.9
Текст программы:
#include <iostream>
using namespace std;
template <class N>
void swapp(N &a, N &b){
N temp = a;
a = b;
b = temp;}
template <>
void swapp <char>(char &a, char &b){
char temp = a;
a = b;
b = temp;}
void main(){
int i = 10 , j = 20;
swapp(i,j);
cout << i << "\t\t" << j << endl;
char ci = 'a', cj = 'b';
swapp(ci,cj);
cout << ci << "\t\t" << cj << endl;}//main
3.3 Индивидуальное задание
Вариант 13
Определить можно ли в двумерном массиве найти такой столбец, который разбивает массив на два так, что сумма элементов в первом больше, чем сумма элементов во втором. Сам столбец в разбиваемые части не входит
Текст программы:
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{const int row = 3;
const int column = 3;
int mass[row][column];
int middle;
int left = 0, right = 0;
srand(time(NULL));
for(int i = 0; i < row; i++)
{for(int j = 0; j < column; j++)
{mass[i][j] = 1 + rand() % 15;
std::cout << ' ' << mass[i][j];}
std::cout << std::endl;}
if(column % 2 == 0)
std::cout << "Takogo stolbca net" << std::endl;
else
{middle = (column + 1) / 2 - 1;
for(int i = 0; i < row; i++)
for(int j = 0; j < middle; j++)
left += mass[i][j];
for(int i = 0; i < row; i++)
for(int j = middle + 1; j < column; j++)
right += mass[i][j];
if(left > right)
std::cout << "Takoi stolbec est': " << middle << std::endl;
else
std::cout << "Takogo stolbca net" << std::endl;}
return 0;}
4. ДВУМЕРНЫЕ МАССИВЫ
4.1 Теоретическая часть
Многомерные массивы
По определению, многомерные массивы как таковые в С++ не существуют, массив всегда считается одномерным. Однако в С++ разрешено объявлять одномерные массивы массивов (т.е. многомерные массивы). Они задаются указанием размера каждой размерности в квадратных скобках.
Например, описание двумерного массива из 6 строк по 8 столбцов: int matr [6][8]; интерпретируется как одномерный массив с именем matr из 6 элементов типа int[8].
Трехмерный массив double prim [6][4][2]; интерпретируется как одномерный массив с именем prim, включающий 6 элементов, каждый из которых имеет тип double [4][2]. В свою очередь, каждый из этих элементов есть одномерный массив из четырех элементов типа double [2]. И, наконец, каждый из этих элементов является массивом из двух элементов типа double.
Для доступа к элементу многомерного массива указываются все его индексы, например: matr[i][j], prim [i][j][k];.
Формы инициализации массива:
При структурной инициализации многомерный массив представляется как массив массивов, при этом каждый массив заключается в свои фигурные скобки. При бесструктурной инициализации задается общий список элементов в том порядке, в котором элементы располагаются в памяти.
Многомерные массивы могут инициализироваться и без указания размера самой левой размерности. Компилятор в этом случае определяет число элементов по числу членов в списке инициализации.
В памяти многомерный массив располагается в последовательных ячейках по слоям (строкам). Элементы с меньшими значениями индекса хранятся в более низких адресах памяти. Многомерные массивы располагаются таким образом, что самый правыйиндекс возрастает самым первым.
Двумерные массивы
Характерным объектом программирования являются двумерные массивы (матрицы). Часто рассматриваются матрицы специального вида - единичные, диагональные, треугольные, разреженные и др. Представление матрицы каждого из видов в программе может быть различным; например, диагональные матрицы могут представляться одномерным массивом.
Запомним некоторые свойства квадратных матриц:
- если номер строки i элемента матрицы A совпадает с номером столбца j, т.е. i==j, это означает, что элемент A[i][i] лежит на главной диагонали матрицы;
- если номер строки i элемента матрицы A превышает номер столбца j, т.е. i>j, это означает, что элемент A[i][j] находится ниже главной диагонали,
- если номер столбца j элемента матрицы A больше номера строки i, т.е. i<j, это означает, что элемент A[i][j] находится выше главной диагонали;
- если индексы элемента A[i][j] матрицы А удовлетворяют равенству i==N-j-1 , это означает, что элемент A[i][j] лежит на побочной диагонали;
- если индексы элемента A[i][j] матрицы А удовлетворяют неравенству i<N-j-1 , это означает, что элемент A[i][j] находится выше побочной диагонали;
- если индексы элемента A[i][j] матрицы А удовлетворяют неравенству i>N-j-1 , это означает, что элемент A[i][j] находится ниже побочной диагонали.
...Подобные документы
Разработка блок-схемы и программы обработки одномерного массива с доступом к элементам с помощью индексов и с помощью указателей. Словесное описание алгоритма и пользовательского интерфейса, листинг программы обработки матрицы и результат её выполнения.
курсовая работа [391,1 K], добавлен 30.09.2013Запись кодов команд программы и констант в FlashROM, кодов исходных данных в EEPROM, требуемых значений установочных битов (Fuse Bits) и битов защиты (Lock Bits). Запись и чтение кодов при программировании, способы программирования в микроконтроллерах.
контрольная работа [24,2 K], добавлен 22.08.2010Изучение функций и возможностей среды разработки языка программирования Pascal. Рассмотрение работы с одномерными и двумерными массивами, со строками и числами. Математическая формулировка задач. Разработка алгоритмов, описание структуры программ.
курсовая работа [879,8 K], добавлен 11.02.2016Изучение применяемых в программировании и информатике структур данных, их спецификации и реализации, алгоритмов обработки данных и анализ этих алгоритмов. Программа определения среднего значения для увеличивающегося количества чисел заданного типа.
контрольная работа [16,0 K], добавлен 19.03.2015Решение инженерных задач при работе с визуальными данными. Базовые структуры данных. Базовые операции над многомерными числовыми массивами. Калибровка камер, элементы восстановления пространственной структуры. Анализ движения, слежение за объектами.
курсовая работа [4,5 M], добавлен 21.06.2011Вычисление выражений, использование стандартных функций; работа с графикой. Порядок действий при вычислении, способы ввода данных с клавиатуры. Построение таблиц функций. Организация циклов в программе, итерационные процессы. Работа с массивами чисел.
контрольная работа [614,7 K], добавлен 16.09.2012Основные особенности эволюционных алгоритмов. Описание алгоритмов селекции, мутации, скрещивания, применяемых для реализации генетических алгоритмов. Вычисление функции приспособленности. Программная реализация. Тестирование и руководство пользователя.
курсовая работа [1,3 M], добавлен 11.03.2014Изучение определения, описания и вызова функций, указателей и ссылок на них. Написание функции умножения произвольного столбца двумерного массива на const. Умножение 2 столбцов массива на константы. Составление блок-схемы алгоритма и текста программы.
лабораторная работа [182,3 K], добавлен 09.01.2012Описание особенностей программирования циклических алгоритмов на С/С++. Использование операторов цикла для организации повтора в программе определенных действий. Создание и реализация программы приближенного вычисления интеграла методом трапеций.
лабораторная работа [86,3 K], добавлен 25.03.2019Целые числа в позиционных системах счисления. Недостатки двоичной системы. Разработка алгоритмов, структур данных. Программная реализация алгоритмов перевода в различные системы счисления на языке программирования С. Тестирование программного обеспечения.
курсовая работа [593,3 K], добавлен 03.01.2015Составление алгоритмов и написание программ циклической структуры с использованием векторов, указателей и векторов указателей на вектор на языке C++. Статическое и динамическое распределение памяти. Функция ввода и обработки элементов вектора или матрицы.
контрольная работа [210,5 K], добавлен 25.03.2015Введение в API-программирование. Транслирование клавиатурных сообщений в ASCII-коды. Текст программы на 32-битном ассемблере с применением API-функций. Функция для создания диалогового окна. Определение открываемого диска, каталога и имени файла.
курсовая работа [40,6 K], добавлен 18.05.2014Специфика понятия "плагиат" в программировании. Схема работы модулей инструментальной системы поиска плагиата. Основы поиска в исходных кодах программ, в произвольных текстах. Обзор инструментальных средств. Программная реализация модуля PlagiatSearch.
магистерская работа [4,9 M], добавлен 27.06.2014Разработка иерархии классов, содержащей не менее трех уровней. Определение базовых и производных классов. Анализ технического задания. Проектирование структуры программы и базовых алгоритмов. Программная реализация разработанной структуры и алгоритмов.
курсовая работа [34,9 K], добавлен 11.01.2011Общие сведения о языке С++. Операции и выражения, стандартные функции и структура программы. Использование функций при программировании на С++. Основные алгоритмы обработки массивов. Статические и динамические матрицы. Организация ввода-вывода в C++.
учебное пособие [6,7 M], добавлен 28.03.2014Анализ затрат и прибыли. Создание программного проекта для решения задачи о прибыли и убытках на языке программирования C#. Использование функций и переменных, компиляция программы. Алгоритмы и структуры данных. Тестирование программного обеспечения.
курсовая работа [1,2 M], добавлен 03.01.2015Понятие процедур и функций, их параметры, отличия и особенности спецификаций и тела. Вызов процедур и функций. Использование хранимых функций в SQL-операторах, уровни строгости для их вызова. Синтаксис удаления процедуры. Перегрузка модульных подпрограмм.
презентация [259,9 K], добавлен 14.02.2014Различные способы обработки информации и программирование в среде Pascal. История создания языка. Блок схема с использованием заголовка функций задания. Описание подпрограмм. Сущность структурного программирования в аспекте написания алгоритмов программ.
курсовая работа [331,9 K], добавлен 18.01.2016Основные типы циклов программирования. Методы применения специальных функций break, continue и цикла while. Обработка массивов информации. Условия применения циклических алгоритмов на языке программирования С++. Инициализация одномерного массива.
курсовая работа [1,7 M], добавлен 06.01.2014Приобретение навыков структурных блок-схем и листингов программ на языке "Ассемблер" для простых микропроцессорных систем управления процессами. Типовые структуры блок-схем алгоритмов обработки данных. Программная реализация типовых функций управления.
методичка [1007,8 K], добавлен 01.10.2010