Консультация № 182719
04.04.2011, 20:34
0.00 руб.
0 19 1
Здравствуйте! Уважаемые эксперты помогите написать 2 программы на С++ желательно в визуале (ну или в dev C++). Заранее спасибо!

дан массив 5х5 для нечётного N (матрица)
пощитать сумму диаганалей i=j. m[n][n] n=5.
1) по индексам (char)
2)*m по адресам (char*)

Обсуждение

Неизвестный
04.04.2011, 22:08
общий
это ответ
Здравствуйте, Посетитель - 369626!
Программа. C++. Компилировал GCC.
Код:
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <locale>

using namespace std;

// Тип данных. По условию char
typedef char data_t;

// Размерность матрицы
const size_t DIM = 5;

// Интервал значений для генерации матрицы
const data_t MIN = -50;
const data_t MAX = 50;

// Генерация значений матрицы

template<size_t DIM>
void fillMatrix(data_t(&matrix)[DIM][DIM])
{
size_t size = DIM*DIM;
data_t *arr = reinterpret_cast<data_t*> (matrix);
while (size--)
{
*arr++ = static_cast<data_t> (static_cast<double> (rand()) / RAND_MAX * (MAX - MIN) + MIN);
}
}

// Печать значений матрицы

template<size_t DIM>
void printMatrix(const char* const msg, const data_t(&matrix)[DIM][DIM])
{
cout << msg << endl;
for (size_t row = 0; row < DIM; ++row)
{
for (size_t col = 0; col < DIM; ++col)
{
cout << setw(4) << static_cast<int> (matrix[row][col]) << ' ';
}
cout << endl;
}
}

// Сумма 1м способом

template<size_t DIM>
int diagSum1(const data_t(&matrix)[DIM][DIM])
{
int sum = 0;
for (size_t i = 0; i < DIM; ++i)
{
sum += matrix[i][i];
}
return sum;
}

// Сумма 2м способом

template<size_t DIM>
int diagSum2(const data_t(&matrix)[DIM][DIM])
{
int sum = 0;
size_t size = DIM;
const data_t * arr = reinterpret_cast<const data_t*> (matrix);
while (size--)
{
sum += *arr;
arr += DIM + 1;
}
return sum;
}

int main()
{
locale::global(locale(""));
srand(time(0));

// Матрица
data_t m[DIM][DIM];

// Заполним матрицу
fillMatrix(m);

// Распечатать
printMatrix("Матрица:", m);

// Результат
cout << "Сумма по индексам:" << diagSum1(m) << endl
<< "Сумма по адресам:" << diagSum2(m) << endl;

#ifdef __WIN32
system("pause");
#endif

return 0;
}

Пример работы:
Код:
Матрица:
-49 31 16 39 -30
-2 14 12 -40 -2
-23 -7 18 7 19
-19 6 25 35 46
0 -7 -13 -5 -10
Сумма по индексам:8
Сумма по адресам:8
Неизвестный
05.04.2011, 13:58
общий
ошибки вылазят(
In function `void fillMatrix(data_t (&)[DIM][DIM])':
86 instantiated from here
28 [Warning] converting to `char' from `double'
Неизвестный
05.04.2011, 14:08
общий
warning это не ошибка, а предупреждение. Приведите полный вывод компилятора.

Неизвестный
05.04.2011, 14:11
общий
я понимаю что это предупреждение и то, что нельзя из чара в дабл. Что значит привести полный вывод компилятора?
Неизвестный
05.04.2011, 14:13
общий
void fillMatrix(data_t(&matrix)[DIM][DIM])
я так понял он на это ругается или не правильно? и если не трудно объясните как эта функция работает
Неизвестный
05.04.2011, 14:23
общий
точность вродь теряется.
Неизвестный
05.04.2011, 14:26
общий
Из double в char можно, как и наоборот. Но при переводе из большего к меньшему компилятор выдает предупреждение на всякий случай. Может программист ошибся. Полный вывод компилятора это все 86 сообщений, которые он выдал.
Какой компилятор используете?
Неизвестный
05.04.2011, 14:28
общий
понятно. Так как мне привести полный вывод компилятора и исправить ошибку?
Неизвестный
05.04.2011, 14:28
общий
Dev-C++ 4.9.9.2
Неизвестный
05.04.2011, 14:31
общий
Ок. Через час доберусь домой и погоняю в нём. Хотя, Dev C++ основан на GCC и проблем быть не должно.
Неизвестный
05.04.2011, 14:34
общий
так да я раньше тоже прогал когда дома в GCC не было проблем, а тут его нет ... ток Dev стоит и не рабит... не знаю что делать)
Неизвестный
05.04.2011, 14:50
общий
спасибо жду!)
Неизвестный
05.04.2011, 15:18
общий
вот я сейчас свой вариант написал по индексам
не могли бы вы более простой предложить для адресов. просто type мы ещё не проходили, препод ругаться будетДля индексов вроде вот так. А как с адресами и если не трудно расскажите чем должно отличаться.
#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

const int N=5;
double m[N][N];
int main()
{
double s=0;
int i=0, j=0;
ifstream inputStream("tempfile.txt");
while(i<N)
{
j=0;
while(j<N)
{
inputStream >> m[i][j];
j++;
}
i++;
}
inputStream.close();
i=0;
while (i != N)
{
s = s + m[i][i];
i++;
}
cout <<"\nResults s: " << s << endl;
system("pause");
}
Неизвестный
05.04.2011, 15:22
общий
См. в ответе. Явное приведение к типу добавил в функции fillMatrix(). Странно, но Dev-C++ воспринимает предупреждение как ошибку.
Неизвестный
05.04.2011, 15:25
общий
Насчет по адресам см. diagSum2(). Отличается тем, что используется указатель, а не индекс.
Неизвестный
05.04.2011, 15:32
общий
А чего матрица имеет тип double? Я так понял из этого
*m по адресам (char*)
что тип char.
Код:
#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

const int N = 5;
double m[N][N];

int main()
{
double s = 0;
ifstream inputStream("tempfile.txt");
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
{
inputStream >> m[i][j];
}
}

int i = N;
double* ptr = reinterpret_cast<double*> (m);

while (i--)
{
s += *ptr;
ptr += N + 1;
}
cout << "\nResults s: " << s << endl;

#ifdef __WIN32
system("pause");
#endif

return 0;
}
Неизвестный
05.04.2011, 16:42
общий
хм ну тут может и опечатка да матрица имеет тип char

это вы по адресам написали что ли?
#ifdef __WIN32
#endif хм это что за пункты?
и что такое ptr. И если не трудно объясните где тут адресация. Я так понял адресация это мы должны ссылаться на некие адреса, которые ввели раньше, чтобы прога работала.

#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

const int N = 5;
double m[N][N];

int main()
{
double s = 0;
ifstream inputStream("tempfile.txt");
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
{
inputStream >> m[i][j];
}
}

int i = N;
double* ptr = reinterpret_cast<double*> (m);

while (i--)
{
s += *ptr;
ptr += N + 1;
}
cout << "\nResults s: " << s << endl;

#ifdef __WIN32
system("pause");
#endif

return 0;
}
Неизвестный
05.04.2011, 16:51
общий
Код:
#ifdef __WIN32
system("pause");
#endif

Строки начинающиеся с # - директивы препроцессора. Если установлена переменная __WIN32, что имеет место под Windows, то компилятор будет компилировать строки между #ifdef и #endif. И консольное окно закрываться не будет автоматически после завершения программы. Т.к. Вы и так работаете под Windows, можете это дело убрать и оставить только вызов system. Для пользователей других систем это поможет избежать некрасивого сообщения из за отсутствия команды pause.

Здесь мы присваиваем указателю ptr адрес m.
Код:
double* ptr = reinterpret_cast<double*> (m);

Ну, а далее в цикле используем.
Неизвестный
05.04.2011, 17:16
общий
ясно спасибо большое!)
Форма ответа