Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Примеры решения задач и использованием массивов




 

Задача 1. Формирование массива с помощью датчика случайных чисел.

Для того чтобы сформировать массив необходимо организовать цикл для перебора элементов массива. Для формирования каждого элемента вызывается функция rand(),которая возвращает псевдослучайное число из диапазона от 0 до 32767. Чтобы получить значения из диапазона от 0 до 100 используется операция получения остатка от деления %.  Если нужно получить не только положительные, но и отрицательные числа вычитается число k равное половине от требуемого диапазона.

a[I]=rand()%100-50;//числа из диапазона -50..49.

Чтобы использовать функцию rand(), надо подключить библиотечный файл <stdlib.h>

 

#include <iostream.h>

#include <stdlib.h> //файл с описанием функции rand()

void main()

{

int a[100];

int n;

cout<<”\nEnter the size of array:”;cin>>n;

for(int I=0;I<n;I++)

{

a[I]=rand()%100;// числа из диапазона 0..100

cout<<a[I]<<” ”; //вывод элемента массива

}

}

Задача 3. Найти максимальный элемент массива.

Для решения этой задачи нужно сформировать массив, присвоить начальное значение в переменную max, в качестве начального значения выступает первый элемент массива, а затем сравнить каждый элемент массива с переменной max. Если значение элемента будет больше max, то его значение записывается в max и последующие элементы сравниваются уже с этим значением.

 

#include <iostream.h>

#include <stdlib.h>

void main()

{

int a[100];

int n;

cout<<”\nEnter the size of array:”;

cin>>n;

for(int I=0;I<n;I++)   //заполнение массива

{

a[I]=rand()%100-50;

cout<<a[I]<<” ”;

 }

 

int max=a[0]; //задаем начальное значение max

for(I=1;I<n;I++)

//сравниваем элементы массива с max

if(a[I]>max)max=a[I];

 

cout<<”\nMax=”<<max;

}

 

Задача 3. Найти сумму элементов массива с четными индексами.

Для решения этой задачи можно предложить несколько способов.

  1. Массив перебирается с шагом 2 и все элементы суммируются.
  2. Массив перебирается с шагом 1 и суммируются только элементы, имеющие четные индексы. Для проверки на четность используется операция получения остатка от деления на 2.

 

//Первый способ

#include <iostream.h>

#include <stdlib.h>

void main()

{

int a[100];

int n;

cout<<”\nEnter the size of array:”;

cin>>n;

for(int I=0;I<n;I++)

{

//заполнение массива случайными числами

a[I]=rand()%100-50;

cout<<a[I]<<” ”;

}

int Sum=0;

for(I=0; I<n; I+=2)

//суммируются элементы с индексами 0, 2, 4, и т. д.

Sum+=a[I];

 

cout<<”\nSum=”<<Sum”;

}

 

 

//Второй способ

#include <iostream.h>

#include <stdlib.h>

void main()

{

int a[100];

int n;

cout<<”\nEnter the size of array:”;

cin>>n;

for(int I=0;I<n;I++)

{

//заполнение массива случайными числами

a[I]=rand()%100-50;

cout<<a[I]<<” ”;

}

int Sum=0;

for(I=0; I<n; I++)

if(I%2==0)

//суммируются элементы с индексами 0, 2, 4, и т. д.

Sum+=a[I];

 

cout<<”\nSum=”<<Sum”;

}

 

Указатели

 

Понятие указателя

 

Указатели являются специальными объектами в программах на C/C++. Указатели предназначены для хранения адресов памяти.

Когда компилятор обрабатывает оператор определения переменной, например, int i=10;, то в памяти выделяется участок памяти в соответствии с типом переменной (для int размер участка памяти составит 4 байта) и записывает в этот участок указанное значение. Все обращения к этой переменной компилятор заменит адресом области памяти, в которой хранится эта переменная.

Рис. 5 Значение переменной и ее адрес

Программист может определить собственные переменные для хранения адресов областей памяти. Такие переменные называются указателями. Указатель не является самостоятельным типом, он всегда связан с каким-то другим типом.

Указатели делятся на две категории: указатели на объекты и указатели на функции. Рассмотрим указатели на объекты, которые хранят адрес области памяти, содержащей данные определенного типа.

В простейшем случае объявление указателя имеет вид:

 

тип* имя;

Знак *, обозначает указатель и относится к типу переменной, поэтому его рекомендуется ставить рядом с типом, а от имени переменной отделять пробелом, за исключением тех случаев, когда описываются несколько указателей. При описании нескольких указателей знак * ставится перед именем переменной-указателя, т. к. иначе будет не понятно, что эта переменная также является указателем.

 

int* i;

double *f, *ff;//два указателя

char* c;

 

Тип может быть любым, кроме ссылки.

 

Размер указателя зависит от модели памяти. Можно определить указатель на указатель: int** a;

Указатель может быть константой или переменной, а также указывать на константу или переменную.

 

int i;   //целая переменная

const int ci=1; //целая константа

int* pi; //указатель на целую переменную

const int* pci; //указатель на целую константу

 

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

 

//указатель на целую переменную

int* pi=&i;  

//указатель на целую константу

const int* pci=&ci;

 

//указатель-константа на переменную целого типа

int* const cpi=&i;

 

//указатель-константа на целую константу

const int* const cpc=&ci;

 

Если модификатор const относится к указателю (т. е. находится между именем указателя и *), то он запрещает изменение указателя, а если он находится слева от типа (т. е. слева от *), то он запрещает изменение значения, на которое указывает указатель.

Для инициализации указателя существуют следующие способы:

· с помощью операции получения адреса

int a=5;

int* p=&a; или int p(&a);

· с помощью проинициализированного указателя

int* r=p;

· адрес присваивается в явном виде

char* cp=(char*)0х В800 0000;

где       0х В800 0000 – шестнадцатеричная константа,

(char*) – операция приведения типа.

· присваивание пустого значения:

int* N=NULL;

int* R=0;

 

Динамическая память

 

Все переменные, объявленные в программе размещаются в одной непрерывной области памяти, которую называют сегментом данных (64 Кб). Такие переменные не меняют своего размера в ходе выполнения программы и называются статическими. Размера сегмента данных может быть недостаточно для размещения больших массивов информации. Выходом из этой ситуации является использование динамической памяти. Динамическая память – это память, выделяемая программе для ее работы за вычетом сегмента данных, стека, в котором размещаются локальные переменные подпрограмм и собственно тела программы.

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

Для создания динамических переменных используют операцию new, определенную в C++:

 

указатель = new имя_типа[инициализатор];

где инициализатор – выражение в круглых скобках.

 

Операция new позволяет выделить и сделать доступным участок динамической памяти, который соответствует заданному типу данных. Если задан инициализатор, то в этот участок будет занесено значение, указанное в инициализаторе.

 

int* x=new int(5);

 

Для удаления динамических переменных используется операция delete, определенная в C++:

 

delete указатель;

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

 

delete x;

 

Операции с указателями

 

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

· разыменование (*);

· присваивание;

· арифметические операции (сложение с константой, вычитание,
инкремент ++, декремент --);

· сравнение;

· приведение типов.

Операция разыменования предназначена для получения значения переменной или константы, адрес которой хранится в указателе. Если указатель указывает на переменную, то это значение можно изменять, также используя операцию разыменования.

 

int a; //переменная типа int

int* pa=new int; //указатель и выделение памяти под //динамическую переменную

*pa=10;//присвоили значение динамической
//переменной, на которую указывает указатель

a=*pa;//присвоили значение переменной а

 

Присваивать значение указателям-константам запрещено.

Приведение типов. На одну и ту же область памяти могут ссылаться указатели разного типа. Если применить к ним операцию разыменования, то получатся разные результаты.

 

int a=123;

int* pi=&a;

char* pc=(char*)&a;

float* pf=(float*)&a;

printf("\n%x\t%i",pi,*pi);

printf("\n%x\t%c",pc,*pc);

printf("\n%x\t%f",pf,*pf);

 

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

 

66fd9c 123

66fd9c {

66fd9c 0.000000

 

Т. е. адрес у трех указателей один и тот же, но при разыменовании получаются разные значения в зависимости от типа указателя.

В примере при инициализации указателя была использована операция приведения типов. При использовании в выражении указателей разных типов, явное преобразование требуется для всех типов, кроме void*. Указатель может неявно преобразовываться в значения типа bool, при этом ненулевой указатель преобразуется в true, а нулевой в false.

Арифметические операции применимы только к указателям одного типа.

· Инкремент увеличивает значение указателя на величину sizeof(тип).

 

char* pc;

int* pi;

double* pd;

. . . . .

pc++;  //значение увеличится на 1

pi++;  //значение увеличится на 4

pd++;  //значение увеличится на 8

 

· Декремент уменьшает значение указателя на величину sizeof(тип).

· Разность двух указателей – это разность их значений, деленная на размер типа в байтах.

int a=123, b=456, c=789;

int* pi1=&a;

int* pi2=&b;

int* pi3=&c;

printf("\n%x",pi1-pi2);

printf("\n%x",pi1-pi3);

 

Результат выполнения программы:

 

1

2

 

Суммирование двух указателей не допускается.

 

· Можно суммировать указатель и константу:

 

pi3=pi3+2;

pi2=pi2+1;

printf("\n%x\t%d",pi1,*pi1);

printf("\n%x\t%d",pi2,*pi2);

printf("\n%x\t%d",pi3,*pi3);

 

Результат выполнения программы:

 

66fd9c 123

66fd9c 123

66fd9c 123

 



Ссылки

Ссылка – это синоним имени объекта, указанного при инициализации ссылки.

Формат объявления ссылки

 

тип & имя =имя_объекта;

 

int x;  // определение переменной

int& sx=x; // определение ссылки на переменную х

const char& CR=’\n’; //определение ссылки на константу

 

Правила работы со ссылками:

· Переменная-ссылка должна явно инициализироваться при ее описании, если она не является параметром функции, не описана как extern или не ссылается на поле класса.

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

· Не существует указателей на ссылки, массивов ссылок и ссылок на ссылки.

· Операция над ссылкой приводит к изменению величины, на которую она ссылается.

Ссылка не занимает дополнительного пространства в памяти, она является просто другим именем объекта.

 

#include<iostream.h>

void main()

{

int i=123;

int& si=i;

cout<<”\ni=”<<i<<” si=”<<si;

i=456;

cout<<”\ni=”<<i<<” si=”<<si;

i=0;

cout<<”\ni=”<<i<<” si=”<<si;

}

 

Выведется:

i=123 si=123

i=456 si=456

i=0 si=0

 

 

Указатели и массивы










Последнее изменение этой страницы: 2018-04-12; просмотров: 344.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...