Задачи с двумерными массивами
Вычислить сумму произведений элементов
y = ∑in-1 ∏jn-1aij
# include <iostream.h>
const int n=5;
void main()
{
int a[n] [n];;
int i, j, y, p;
//Ввод массива с клавиатуры
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;
}
y=0;
for (i=0; i<n; i++)
{
p=1;
for (j=0; j<n; j++) p=p*a[i][j];
y=y+p;
}
cout<<”y=”<<y<<endl;
}
Найти максимальную из построчных сумм
Y= Max ∑ a[i][j]
# include <iostream.h>
const int n=30;
void main()
{
int a[n] [n];;
int i, j, y, max;
//Ввод массива с клавиатуры
cout<<”enter array a:”<<endl;
for (i=0; i<n; i++)
for (j=0; j<n; j++)
cin>>a[i][j];
//Вывод массива на экран
cout<<”massive a”<<endl;
for (i=0; i<n; i++)
{
for (j=0; j<n; j++) cout<<a[i][j]<<’ ’;
cout<<endl;
}
max=0;
for (j=0; j<n; j++)
max=max+a[0][j];
for (i=1; i<n; i++)
{
y=0;
for (j=0;j<n; j++)
y=y+a[i][j];
if(y> max) max =y;
}
cout<<”max=”<<max<endl;
}
EA- и AE–предикаты
a) AiEj( a[i][j]>0)
В каждой строке матрицы существует хотя бы один положительный элемент.
# include <iostream.h>
const int n=30;
void main()
{
int a[n] [n];;
int i, j;
//Ввод массива с клавиатуры
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;
}
bool p=true;
for (i=0;i<n&&p;i++)
{
bool q=false;
for (j=0; j<n&&!q; j++)
if (a[i][j]>0) q=true;
p=q;
}
cout<<”p=”<<p<<endl;
}
b) EiAj[ a[i][j]>0 ]
Существует строка матрицы, состоящая из положительных элементов.
# include <iostream.h>
const int n=30;
void main()
{
int a[n] [n];;
int i, j;
//Ввод массива с клавиатуры
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;
}
bool p=false;
for (i=0;i<n&&!p;i++)
{
bool q=true;
for (j=0; j<n&&q; j++)
if (a[i][j]<=0) q=false;
p=q;
}
cout<<”p=”<<p<<endl;
}
c) AiAj[ a[i][j]>0]
Все элементы матрицы положительны
# include <iostream.h>
const int n=30;
void main()
{
int a[n] [n];;
int i, j;
//Ввод массива с клавиатуры
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;
}
bool p=true;
for (i=0;i<n&&p;i++)
for (j=0; j<n&&p; j++)
if (a[i][j]<0) p= false;
cout<<”p=”<<p<<endl;
}
d) EiEj[ a[i][j]>0]
В матрице существует хотя бы один положительный элемент
# include <iostream.h>
const int n=30;
void main()
{
int a[n] [n];;
int i, j;
//Ввод массива с клавиатуры
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;
}
bool p=false;
for (i=0;i<n&&!p;i++)
for (j=0; j<n&&!p; j++)
if (a[i][j]>0) p= true;
cout<<”p=”<<p<<endl;
}
Умножение матриц
С=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
}
Функции