Цель лекции: изучить понятия, особенности внутреннего представления, способов генерации и вывода одномерных массивов, научиться выполнять объявление, инициализацию, генерацию и вывод массивов при решении задач на языке C++.
В программировании часто возникают задачи, связанные с обработкой больших объемов данных. Для того, чтобы весь этот объем данных хранить внутри программы, применяют массивы – простейшую разновидность
). Каждая такая область памяти называется элементом массива. Массивы обладают размерностью (большей или равной единице), которой задается число элементов, содержащихся в них, а также измерением, что предполагает возможность описания в программе одно- и многомерных массивов. Количество элементов в массиве называется его размером.
(рис 10.1) Схематическое представление массивовПростейшим аналогом двумерного массива может быть таблица, а трехмерного – несколько таблиц одинакового размера. Математические объекты типа вектор и матрица – примеры аналогов (соответственно одно- и двумерных) массивов.
Тип элемента массива может быть одним из базовых (
Элементы массива в С++ нумеруется, начиная с нуля. У одномерных массивов после его имени указывается один индекс (порядковый номер), заключенный в прямоугольные скобки [ ], а у многомерных – несколько, каждый из которых заключается в [ ]. Последнее означает, что
Все элементы массива имеют одно имя – имя массива и отличаются индексами – порядковыми номерами в массиве. В определении массива можно задать его размерность по каждому измерению. Допустимо явное задание массива либо с помощью указателя (объекта, хранящего адрес начала области набора значений). Резервирование памяти для массива выполняется на этапе компиляции программы.
При объявлении массива компилятор выделяет для него последовательность ячеек памяти, для обращения к которым в программе применяется одно и то же имя. В то же время массив позволяет получить прямой доступ к своим отдельным элементам.
Синтаксис определения массива без дополнительных
Тип ИмяМассива[ВыражениеТипаКонстанты];
или
Тип ИмяМассива[];
ИмяМассива – идентификатор массива.
Тип – тип элементов объявляемого массива. Элементами массива не могут быть функции, файлы и элементы типа void.
ВыражениеТипаКонстанты – задает количество элементов (
Например:
int a[100]; //массив из 100 элементов целого типа double d[14]; // массив из 14 элементов типа doublechar s[]="Программирование"; //символьный массив const int t=5, k=8; float wer[2*t+k]; //массив из 2*t+k элементов вещественного типа
int sample[853]; /*массив из элементов sample[0], sample[1], sample[2],...,sample[852] типа int*/равносильно объявлению
const int N_max=853; int sample[N_max];равносильно объявлению
#define N_max 853 ... int sample[N_max];
В языке С++ не производится проверки границ массивов: таким образом, исполнение кода не остановится при выходе за границы массива. Если N и указать индекс элемента, выходящий за пределы N, что не приведет к появлению сообщений об ошибке, как на шаге компиляции, так и на шаге выполнения, даже если это послужит причиной аварийного завершения программы.
Термином "инициализация" обозначают возможность задать начальные значения элементов массива без программирования соответствующих действий. Например, не прибегая к программным средствам типа присваивания значений в цикле или считывания данных из внешнего источника (файл, клавиатура,
В С++ одновременно с объявлением массива можно задать начальные значения всех элементов массива или только нескольких первых его компонент.
Например:
float t[5]={1.0, 4.3, 8.1, 3.0, 6.74};
char b[7]={'П','р','и','в','е','т'};
/*в данных примерах длину массива компилятор вычисляет по
количеству начальных значений, перечисленных в фигурных
скобках*/
int d[10]={1, 2, 3};
char a[10]="Привет";
/*в данных примерах определяется значение только заданных
переменных d[0],d[1],d[2] и a[0],a[1],...,d[9], остальные
элементы не инициализируются*/
Если в определении массива явно указан его размер, то количество начальных значений не может быть больше количества элементов в массиве.
Пусть необходимо проинициализировать массивы для
char e1[12] = "read error\n"; char e2[13] = "write error\n"; char e3[18] = "cannot open file\n";
Компилятор С++ сам сформирует нужное значение по количеству инициализирующих данных. В нашем случае под массив e2 будет отведено 13 байтов, включая последний байт с нулевым кодом, завершающий каждую строку. Оператор
printf("%s имеет длину, равную %d\n",e2,sizeof (e2));
выведет на экран
write error имеет длину, равную 13
Метод инициализации безразмерных массивов не только менее трудоемок, но и позволяет заменить любое сообщение, без перерасчета размера соответствующего массива.
Адресация элементов массива осуществляется с помощью индексированного имени. Синтаксис обращения к элементу массива:
ИмяМассива[ВыражениеТипаКонстанты];
или
ИмяМассива[ЗначениеИндекса];
Обращаться к элементам массива можно также посредством механизма указателей.
Таким образом, чтобы обратиться к элементу массива, надо указать имя массива и номер элемента в массиве (индекс).
Например:
a[0] – индекс задается как константа,
d[55] – индекс задается как константа,
s[i] – индекс задается как переменная,
w[4*p] – индекс задается как выражение.
Следует помнить, что компилятор в процессе генерации кода задет начальный адрес массива, который в дальнейшем не может быть ИмяМассива либо ИмяМассива[0]. Имя массива считается константой-указателем, ссылающимся на адрес начала массива.
Массив занимает непрерывную область памяти. Для одномерного массива полный объем занимаемой памяти в байтах вычисляется по формуле:
Байты = sizeof (тип) * размер массива
Массив представляет собой набор однотипных данных, расположенных в памяти таким образом, чтобы по индексам элементов можно было легко вычислить адрес соответствующего значения. Например, пусть A состоит из элементов, расположенных в памяти подряд по возрастанию индексов, и каждый элемент занимает по k байт. Тогда адрес i -того элемента вычисляется по формуле:
адрес(A[i]) = адрес(A[0]) + i*k
Пример 1. Определение размера памяти одномерного массива.
#include "stdafx.h"
#include <iostream>
using namespace std;
#define v 4
#define p 3
int _tmain(int argc, _TCHAR* argv[]){
const int q=4, r=1;
int i_mas[10];
int k=sizeof(i_mas);
cout << "i_mas[10] занимает " << k << " байт\n";
float f_mas[7]={2.0,4.5,8.3,7.0,1.0};
int t=sizeof(f_mas);
cout << "f_mas[7]={2.0,4.5,8.3,7.0,1.0} занимает "<< t <<"байт\n";
double d_mas[2*q-r];
int w=sizeof(d_mas);
cout << "d_mas[2*q-r] занимает " << w << " байт\n";
double d1_mas[2*v/p];
int w1=sizeof(d1_mas);
cout << "d1_mas[2*v/p] занимает " << w1 << " байт\n";
char c_mas[]="Программирование";
int s=sizeof(c_mas);
cout << "c_mas[]=\"Программирование\"занимает"<< s <<"байт\n";
system("pause");
return 0;
}
Результат выполнения программы:
i_mas[10] занимает 40 байт – 4 байта (тип int ) * 10 (количество элементов массива)
f_mas[7] = {2.0,4.5,8.3,7.0,1.0} занимает 28 байт – 4 байта (тип float ) * 7 (объявленное количество элементов массива)
d_mas[2*q-r] занимает 56 байт – 8 байт (тип double ) * 7 (вычисленное через формулу количество элементов массива)
d1_mas[2*v/p] занимает 16 байт – 8 байт (тип double ) * 2 (вычисленное через формулу количество элементов массива)
c_mas[]="Программирование" занимает 17 байт – 1 байт (тип char ) * 17 (16 знаков + нулевой байт '\0' )
В языке С++ между указателями и массивами существует тесная связь. Например, когда объявлен массив int array[25], этим определяет не только выделение памяти для двадцати пяти элементов массива, но и для указателя с именем array. В языке С++ имя массива без индексов трактуется как адрес начального элемента. То есть имя массива является указателем на массив. Таким образом, доступ к элементам массива осуществляется через указатель с именем array.
Поскольку имя массива является указателем, допустимо, например, такое присваивание:
int arrаy[25]; int *ptr; ptr=array;
Здесь указатель устанавливается на адрес первого элемента массива, причем присваивание можно записать в эквивалентной форме .
Адрес каждого элемента массива можно получить, используя одно из трех выражений:
| Адрес в памяти | 1000 | 1002 | 1004 | 1008 | 1008 | ... | |
| Индекс | 0 | 1 | 2 | 3 | 4 | ... | 24 |
| Значения | 1 | 2 | 3 | 4 | 5 | ... | 25 |
| Адрес i - го элемента | array array[0] ptr |
array +1 array[1] ptr + 1 |
array +2 array[2] ptr + 2 |
array +3 array[3] ptr + 3 |
array +4 array[4] ptr + 4 |
... | array +24 array[24] ptr + 24 |
А обращение к пятому элементу массива можно записать как:
array[4], *( array + 4), *(рtr + 4).
Эти операторы вернут пятый элемент массива.
Таким образом, С++ дает два способа обращения к элементу массива:
Версия с индексированным именем выполняется медленнее, так как в языке С++ на индексирование массива уходит больше времени, чем на выполнение оператора *. Поэтому использование указателей для доступа к элементам массива в языке С++ применяется довольно часто.
Пример 2.
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
int array[10];
int *p;
p=array[0];
/*эквивалентные операции присваивания*/
*array=2; printf("%d\n", array[0]);
array[0]=2; printf("%d\n", array[0]);
*(array+0)=2; printf("%d\n", array[0]);
*p=2; printf("%d\n", array[0]);
p[0]=2; printf("%d\n", array[0]);
*(p+0)=2; printf("%d\n", array[0]);
system("pause");
return 0;
}
В результате выполнения любой из *array=2 и *p=2, так как в них не требуется выполнять операции сложения.
С элементами объявленного массива можно выполнять все действия, допустимые для обычных переменных этого типа (выше был приведен пример целочисленного массива, т.е. типа int ). Например, возможны
hours[4] = 34; hours[5] = hours[4]/2;
или
if (number < 4 hours[number] >= 40) { ... }
Присвоить значения набору элементов массива часто бывает удобно с помощью циклов for или while. Для массивов не допустима операция прямого присваивания.
Задачи по программированию с использованием массивов решаются, как правило, по следующему алгоритму: объявление массива, генерация или инициализация, обработка значений элементов, вывод. При этом, если в
Перед использованием значений элементов массива их необходимо сформировать. Задать значения элементам массива можно на этапе объявления, т.е. выполнить инициализацию, а также непосредственным выполнением присваивания.
В большинстве задач с использованием массивов целесообразно выполнять генерацию массивов – автоматическое формирование значений элементов. Генерацию массива (массивов) в программе оформляют в виде отдельной функции.
Стандартными способами генерация массивов являются:
При этом при формировании значений элементов используют цикл по индексам элементов или
Вывод массивов также целесообразно оформлять в виде отдельной функции. Так как функция вывода не изменяет значения элементов массива, то в качестве одного из параметров такой функции выступает сам массив или указатель на массив. Одномерные массивы удобно выводить в строку или в столбец в зависимости от задачи ( Пример 3 и 4 ). Для организации вывода также используют цикл по индексам элементов или
Пример 3.
/*Генерация целочисленного массива числами с клавиатуры и вывод массива в строку*/
#include "stdafx.h"
#include <iostream>
using namespace std;
#define max 20
void gen (int k,int *pp);//прототип функции генерации массива
void out (int k,int x[max]);//прототип функции вывода массива
int _tmain(int argc, _TCHAR* argv[]){
int a[max],n,*p;
do {
printf("\nВведите количество элементов массива n (n<=20):");
scanf ("%d",n);
}
while (n>max); //проверка выхода за границы массива
p=a;
gen(n,p);
out(n,a);
system("pause");
return 0;
}
//Описание функции генерации массива с клавиатуры
void gen(int k,int *pp){
/*передача указателя как параметра позволяет вернуть
сформированный массив в основную программу*/
int i;
printf("\nВведите значения %d элементов массива: \n",k);
for (i=0;i<k;i++){
printf("x[%d]= ",i);
scanf("%d",pp++);
}
}
//Описание функции вывода массива в строку
void out (int k,int x[max]){
int i;
printf("\nВывод значений %d элементов массива в строку: \n",k);
for (i=0;i<k;i++)
printf("%d\t",x[i]);
}
Пример 4.
/*Описание функции генерации массива значениями элементов арифметической прогрессии*/
void gen(int k,int x[max]) {
int i,d;
printf ("\nВведите нулевой элемент прогрессии: ");
scanf("%d",x[0]);
printf ("\nВведите разность прогрессии: ");
scanf("%d",d);
for (i=1;i<k;i++)
x[i]=x[i-1]+d;
}
Пример 5.
//Описание функции вывода массива в столбец
void out (int k,int x[max]){
int i;
printf("\nВывод значений %d элементов массива в столбец: \n",k);
for (i=0;i<k;i++)
printf("x[%i]= %d\n",i,x[i]);
}
Для использования функции <time.h>.
Для написания кода генерации массива случайными целыми числами используется:
srand(). Синтаксис:void srand(unsigned seed);– функция устанавливает свой аргумент как основу (
seed ) для новой последовательности псевдослучайных целых чисел, возвращаемых функцией rand (). Сформированную последовательность можно воспроизвести. Для этого необходимо вызвать srand() с соответствующей величиной seed .Для использования данной функции необходимо подключить библиотечный файл <stdlib.h>.
rand (). Синтаксис:int rand(void);– функция возвращает
RAND_MAX. Для использования данной функции необходимо подключить библиотечный файл <stdlib.h>.RAND_MAX определяет максимальное значение случайного числа, которое может быть возвращено функцией rand (). Значение RAND_MAX – это максимальное положительное целое число.[a,b). Для этого используются следующие выражения://генерация случайных целых чисел на [a,b) x[i]=rand()%(b-a)+a; //генерация случайных вещественных чисел на [a,b) y[i]= rand()*1.0/(RAND_MAX)*(b-a)+a;
Пример 6.
/*Описание функции генерации массива случайными вещественными числами на[a,b)*/
void gen(int k,int a, int b, float x[max]){
int i;
srand(time(NULL)*1000);
//устанавливает начальную точку генерации случайных чисел
for (i=0;i<k;i++){
x[i]=(rand()*1.0/(RAND_MAX)*(b-a)+a);
//функция генерации случайных чисел на [a,b)
}
}
Генерация массива – это автоматическое формирование значений его элементов.
Значение элемента массива – это значение, хранящееся по адресу, который соответствует данному элементу.
Измерение массива – это количество индексов в определении массива.
Имя массива – идентификатор, именующий выделенную под массив область памяти.
Индекс элемента массива – это порядковый номер элемента в последовательности.
Инициализация массива – это формирование значений его элементов.
Массив – это именованная последовательность областей памяти, хранящих однотипные элементы.
Одномерный массив – это массив, измерение которого равно единице.
Размер массива – это количество элементов в массиве.
– это тип элементов массива.
Указатель на массив – это адрес области памяти, выделенной под массив.
Элемент массива – это каждая область памяти из последовательности областей, выделенных под массив.
Цель работы: изучить понятия, особенности внутреннего представления, способов генерации и вывода одномерных массивов, научиться выполнять объявление, инициализацию, генерацию и вывод массивов при решении задач на языке C++.
При выполнении лабораторной работы для каждого задания требуется написать программу на языке С++, которая получает на входе числовые данные (в зависимости от постановки задачи), выполняет генерацию, вывод одномерного массива указанного типа. Ввод данных осуществляется с клавиатуры с учетом требований к входным данным, содержащихся в постановке задачи. Ограничениями на входные данные является диапазон используемого числового типа данных в языке С++ и максимально допустимый размер объявляемого одномерного массива.
Теоретические сведения.
Ознакомьтесь с материалом лекции 10.
Задания к лабораторной работе.
Выполните приведенные ниже задания.
a и b ( a<b ). Объявите одномерный целочисленный массив, в котором 10 элементов. Выполните генерацию массива первыми десятью цифрами дробной части частного a/b. Выведите массив на экран в столбец. Оформите генерацию и ввод массива с помощью функций. Например, для a =7, b =23 значениями элементов массива будут числа: 3 0 4 3 4 7 8 2 6 0.Указания к выполнению работы.
Каждое задание необходимо решить в соответствии с изученными методами объявления, генерации и вывода одномерных массивов в языке С++. При разработке программного кода требуется использовать метод процедурной абстракции и комментировать фрагменты кода.
Следует реализовать каждое задание в соответствии с приведенными этапами:
Требования к отчету.
Отчет по лабораторной работе должен соответствовать следующей структуре.
Контрольные вопросы
int x[10], y[10];?mas следующие обращения и почему: mas и mas[0]?Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.