Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции 1 семестр.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.21 Mб
Скачать
  1. Умножение матриц

С=A*B

# include <iostream.h>

const int n=3;

void main()

{

int a[n] [n], b[n] [n], c[n] [n];

int i, j, k;

//Ввод массива с клавиатуры

cout<<”enter array a:”<<endl;

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

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

cin>>a[i][j];

//Вывод массива на экран

cout<<”array a:”<<endl;

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

{

for (j=0; j<n; j++) cout<<a[i][j]<<’ ‘;

cout<<endl;

}

//Ввод массива с клавиатуры

cout<<”enter array b”<<endl;

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

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

cin>>b[i][j];

//Вывод массива b на экран

cout<<”array b:”<<endl;

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

{

for (j=0; j<n; j++) cout<<b[i][j]<<’ ’;

cout<<endl;

}

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

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

{

c[i][j]=0;

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

c[i][j]=c[i][j]+a[i][k]*b[k][j];

}

//Вывод массива на экран

cout<<”array c:”<<endl;

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

{

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

cout<<c[i][j]<<’ ’;

cout<<endl;

}

}

Лекция

Указатели.

Указатель – это объект, который содержит некоторый адрес памяти. Этот адрес обозначает местоположение в памяти другого объекта, такого как переменная. Если x содержит адрес переменной y, то о переменной x говорят, что она «указывает» на y.

Формат объявления переменной-указателя таков:

Тип *имя переменной.

Использование символа * перед именем переменной в инструкции объявления превращает эту переменную в указатель.

int *x;

x – укзатель на int.

Операторы, используемые с указателями.

С указателями используются два оператора ”*” и “&”.

Оператор “&”- унарный. Он возвращает адрес памяти, по которому расположен операнд.

int *ptr;

ptr= &total;

В переменную ptr помещается адрес переменной total.

Второй оперантор работы с указателями (“*”) служит дополнением к первому (“&”). Это также унарный оператор , но он обращается к значению переменной , расположенной по адресу , заданному его операндом. Другими словами, он ссылается на значение переменной , адресуемой заданным указателем. Если перменная ptr содержит адрес перменной total , то при выполнении инструкции

val=*ptr;

будет присвоено значение переменной total, на которую указывает переменная ptr.

Все байты в памяти нумеруются. Номер байта - адрес.

int х=5 – инициализация переменной

int *p- объявление указателя;

p- указатель( адрес)

p=&x- взятие адреса

*p=10 – изменение х через указатель

*-операция разыменования (косвенное присвоение)

Ссылки.

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

int y=10;

int & x=y;

cout<<”x= “<<x<<endl;// x=10

* конкретные адреса переменных могут быть другими */

int a;

//переменная с именем "a" типа int размещена по адресу 0xbfd86d6c

int &ra = a;

/* задано альтернативное имя (ra) для переменной по адресу 0xbfd86d6

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

(и эта операция не есть ссылка), то есть &a тут означает получить адрес переменной к которому привязано имя "a" */

cout << &a << '\n' << &ra << '\n';

В stdout будет записано:

0xbfd86d6c 0xbfd86d6c

То есть оба имени "a" и "ra" привязаны к одному и тому же адресу.

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

Важно отличать ссылки от оператора взятия адреса & (address of). Оператор взятия адреса используется для уже созданного объекта с целью получить его адрес (то есть адрес области памяти, где хранятся значения), а ссылка это только задание альтернативного имени объекта (с точки зрения программиста, а не реализации). Например:

int a; //переменная типа int размещена по адресу 0xbfd86d6c с именем "a"

int b = 3;

/* создан указатель с именем "p" по адресу 0xbf971c4c, значение этого указателя адрес объекта с именем "a" - 0xbfd86d6c (это значение можно будет менять)

*/

int *p = &a;

p = &b; //присваиваем указателю новое значение

Пример 1

# include <iostream.h>

void main()

{

int x=10;

int *p;

cout<<”x=”<<x<< endl; // 10

p=&x;

cout<<”p=”<<p<<endl;

//p=0X0012FF7C –адрес ячейки памяти, содержащей int x

*p=20;

cout<<”*p=”<<*p<<endl; //20

cout<<”x=”<<x<< endl; // 20

int & r=x; //& r-ссылка

r=50;

cout<<”r=”<<r<<endl; // 50

cout<<”x=”<<x<< endl; // 50

x=20;

cout<<”r=”<<r<<endl; // 20

cout<<”*p=”<<*p<<endl; //20

}

*Примечание

Ссылка -2ое имя Х, r работает как указатель, автоматически разыменовывается. Память под r не выделяется

Пример 2

# include <iostream.h>

void main()

{

int a[3]={1.2.3};

cout<<” array a:<<endl;

cout<<a[0]<<’ ‘ <<a[1]<<’ ‘ <<a[2]<<endl; // 1_2_3

cout<<”address a:”<<a<<’ ‘<<a+1<<’ ‘<<a+2<<endl ;

// address a: 0x0012FF68 0x0012FF6C 0x0012FF70

//Косвенное изменение массива

int *q=a; //q указатель на int

cout<<”q=”<<q<<’ ’<<q+1<<’ ’<<q+2<<endl;

// q= 0x0012FF68 0x0012FF6C 0x0012FF70

cout<<”*q=”<<*q<<’ ’<<*(q+1)<<’ ’<<*(q+2)<<endl;

//*q=1 2 3

*q=904; *(q+1)=905; *(q+2)=906;

cout<<” array a:”<<endl;

cout<<a[0]<<’ ‘ <<a[1]<<’ ‘<<a[2]<<endl;

// 904 905 906

a[0]=1;

a[1]=2;

a[2]=3;

cout<<” *q= ”<<*q<<’ ’<<*(q+1)<<’ ’<<*(q+2)<<endl ;

//*q=1 2 3

}

Функции

Основы использования функций.

Функции – этьо подпрограммы , которые содержат одну или несколько инструкций. Функции называются строительными блоками С++, поскольку программа в С++ , как правило, представляет собой коллекцию функций.

Общий формат С++ функций

Все С++ функции имеют общий формат

Тип_возвращаемого значения имя (список _параметров)

{

// тело функции

}

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

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

После имени функции в круглых скобках указывается список параметров, который представляет собой список пар ( состоящих из типа данных и имени ), разделенных запятыми.

Параметры – это по сути переменные, которые получают значения аргументов, передаваемых функции при вызове.

Если функции не имеют параметров, то круглые скобки остаются пустыми.

В фигурные скобки заключено тело функции. Тело функции составляют С++-инструкции, которые определяют действие функции. Функция завершается ( и управление передается вызывающей процедуре) при достижении закрывающейся скобки или инструкции return

Создание функции.

#include<iostream>

using namespace std;

void myfunc();// прототип функции myfunc()

void main()

{

cout<<”В функции main().”<<endl;

myfunc();

cout<<”Снова в функции main().”<<endl;

}

// Определение функции myfunc()

void myfunc()

{

cout<<”В функции myfunc().”<<endl;

}

Использользование аргументов

Функции можно передать одно или несколько значений. Значение передаваемое функции называется аргументом. Таким образом, аргументы представляют собой средсьво передачи инициализации в функцию.

При создании функции, которая принимает одно или несколько аргументов, необходимо объявить переменные, которые получат значения этих аргументов. Эти переменные называются параметрами функции.

#include<iostream>

using namespace std;

void box(int length, int width, int height);// прототип функции

void main()

{

box(7,20,4);

box(50,3,2);

box(8,6,9);

}

// Определение функции box()

void box(int length, int width, int height)

{

cout<<” Объем параллелепипеда равен ”<< lengtht* width* height <<endl;

}

Использользование инструкции return

В предыдущих примерах возврат из функции к инициатору ее вызова происходил при обнаружении фигурной скобки. Однако это приемлимо не для всех функций.

Возврат значений.

Использование функции в выражениях

Правила действия областей видимости функций.

Локальная область видимости

Локальные переменные можно объявлять внутри любого блока.

Сокрытие имен

Параметры функции

Глобальная область видимости

Передача указателей и массивов в качестве аргументов функций

Передача функции указателя

Передача функции массива

Передача функциям строк

Возвращение функциями указателей

Оформление функции в С++

Тип имя функции (список формальных параметров);

Типы функции

int

double

char

void (не возвращает значений)

Функция - именованный набор операторов.

Если р1 и р2 функции, и р1 вызывает р2, то р2 должна быть описана раньше р1.

Если тело функции идет после main() , то перед main() должен стоять прототип функции.

Пример 1

Функция плюс

# include <iostream.h>

void plus (int,int,int); // прототип функции plus, параметры переданы по значению

void plus1 (int,int,int&); // прототип функции plus1, последний параметр передан по ссылке

int plus2(int, int) //результат функции число типа int

void main()

{

int a=4; int b=5; int c=10;

cout<<”plus()”<<endl;

plus(a,b,c);

cout<<”c=”<<c<<endl; //9

plus1(a,b,c);

cout<<”c=”<<c<<endl; //10

int c2=plus2(a,b);

cout<<”c2=”<<c2<<endl; //9

// Возможен вариант

cout<<”plus2()=”<<plus2(a,b)<<endl; //9

}

void plus (int x, int y, int z)

{

cout<<”x=”<<x<< endl; //4

cout<<”y=”<<y<< endl; // 5

cout<<”z=”<<z<< endl; // 10

z=x+y;

cout<<”z=”<<z<< endl; // 9

}

void plus1 (int x, int y, int &z)

{

cout<<”x=”<<x<< endl; //4

cout<<”y=”<<y<< endl; // 5

cout<<”z=”<<z<< endl; // 10

z=x+y;

cout<<”z=”<<z<< endl; // 9

}

int plus2 (int x, int y)

{

cout<<”x=”<<x<< endl; //4

cout<<”y=”<<y<< endl; // 5

cout<<”x+y”<<x+y<< endl; // 9

return x+y;

}

Примечание

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

plus2(a+b*c,2*c);

plus2(5,7);

Передача массивов функции.

Пример 2.

# include <iostream.h>

const int n=10;

void create ( int x[], int k);

//возможный вариант void vvod ( int x[n])

void show ( int x[], int k);

int max (int x[], int k);

void main()

{

int a[n];

create(a,n);

show ( a, n);

cout<< “max(a,n)= ”<<max(a,n)<<endl;;

}

void create ( int x[], int k)

{

int i;

for (i=0; i<k; i++)

{

cout<<”x[“<<i<<”]=”;

cin>>x[i];}

}

}

void show ( int x[], int k)

{

int i;

for (i=0; i<k; i++)

cout<<x[i]<<”_”;

}

int max(int x[], int k)

{

int i;

int m;

m=a[0];

for (i=0; i<k; i++)

if (m<x[i]) m=x[i];

return m;

}

Лекция №9

Динамические массивы

Задание статического массива

const int n=10;

int a[n];

Задание динамического массива

int n;

cout<< “Enter n:”;

cin>>n;

int*b //указатель на первый элемент массива

b= new int[n];

delete [] b - после работы программы необходимо освободить память «кучи» от b.

В параметрах функций динамический массив задается так же, как и статический

void vvod ( int x[], int n);

Или

void vvod ( int *x, int n);

void vvod ( int x[n])

Примечание

int*p;

p=new int;

*p=10; (косвенная динамическая память)

delete p ; (возврат памяти)

Задание двумерного динамического массива

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

int colstr; colstb;

cout<< “Enter colstr:”;

cin>> colstr;

cout<< “Enter colstb:”;

cin>> colstb;

int **b;

b=new int*[colstr];

for (int i<0;i<colstr;i++)

b[i]=new int[colstb];

Соответственно, необходимо delete[][]b;

В параметрах функций

void create ( int **x, int n, int m);

void show( int **x, int n, int m);

Задача 1.

Даны два двумерных массива A и B (квадратные матрицы).

Матрица С= A* B, если в А существует строка простых чисел. В противном случае С= A+ B

# include <iostream.h>

# include <math.h>

void create ( int **, int);

void show( int **, int);

bool prime (int);

bool EA( int **, int);

void mult ( int **, int**, int**);

void add ( int **, int**, int**);

void main()

{

int n;

cout<<”enter size=”;

cin>>n;

int **a, **b, **c;

a= new int*[n];

int i;

for (i<0;i<n;i++)

a[i]=new int[n];

b= new int*[n];

for (i<0;i<n;i++)

b[i]=new int[n];

c= new int*[n];

for (i<0;i<n;i++)

c[i]=new int[n];

create(a,n);

create(b,n);

if (EA(a,n)) mult(a,b,c);

else add(a,b,c);

cout<<”array c:”<<endl;

show(c,n);

delete[][]a;

delete[][]b;

delete[][]c;

}