powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Умножение матриц
62 сообщений из 62, показаны все 3 страниц
Умножение матриц
    #38654935
Armagedon4uk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помогите исправить а то я не очень понимаю как записать умножение матриц. Вот то что я сделал.Если что могу всю програму скинуть

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
int l,a,b;
double s;
for(a=0;a<StringGrid1->RowCount;a++)
{
for(l=0;l<StringGrid2->ColCount;l++)
{
s=0;
for(b=0;b<StringGrid1->ColCount;b++)
{
s=s+StringGrid1->Cells[a][b]*StringGrid2->Cells[l][a];
StringGrid3->Cells[a][b]=s;
}
}
}
...
Рейтинг: 0 / 0
Умножение матриц
    #38654938
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Armagedon4ukВот то что я сделал.
StringGrid, как явствует из названия, хранит строки. Чего надо обкуриться чтобы пытаться
умножать строку на строку?.. Приводи строки к значениям нужного (перемножательного) типа
перед использованием.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Умножение матриц
    #38654983
Armagedon4uk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

А как это сделать?
...
Рейтинг: 0 / 0
Умножение матриц
    #38654984
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Armagedon4ukА как это сделать?
С помощью одной из функций StrTo* это обычно делается, но есть и другие способы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Умножение матриц
    #38655035
Armagedon4uk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

Спасибо это помогло. Но теперь у меня другая проблема. Кажеться он неверно умножает. Посмотрите сами вот скрин и програма.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int i=0,j=0,q=0,w=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
if(StringGrid1->Cells[i][j]=="")
{
StringGrid1->Cells[i][j]=StrToInt(Edit5->Text);
i++;
if(i==StringGrid1->ColCount)
{
i=0;
j++;
}
}
Edit5->SetFocus();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int h,r;
h=StrToInt(Edit1->Text);
StringGrid1->ColCount=h;
r=StrToInt(Edit2->Text);
StringGrid1->RowCount=r;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
int x,z;
x=StrToInt(Edit4->Text);
StringGrid2->ColCount=x;
z=StrToInt(Edit3->Text);
StringGrid2->RowCount=z;
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button4Click(TObject *Sender)
{
if(StringGrid2->Cells[q][w]=="")
{
StringGrid2->Cells[q][w]=StrToInt(Edit6->Text);
q++;
if(q==StringGrid2->ColCount)
{
q=0;
w++;
}
}
Edit6->SetFocus();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button5Click(TObject *Sender)
{
for(int i=0;i<StringGrid1->ColCount;i++) {
    for(int j=0; j<StringGrid1->RowCount;j++) {
      StringGrid1->Cells[i][j] = "";
    }
  }
  for(int q=0;q<StringGrid1->ColCount;q++) {
    for(int w=0; j<StringGrid1->RowCount;w++) {
      StringGrid1->Cells[q][w] = "";
    }
  }
  i=0;
  j=0;
  q=0;
  w=0;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button6Click(TObject *Sender)
{
int l,a,b,m,n;
double s;
for(a=0;a<StringGrid1->RowCount;a++)
{
for(l=0;l<StringGrid2->ColCount;l++)
{
s=0;
for(b=0;b<StringGrid1->ColCount;b++)
{
m=StrToFloat(StringGrid1->Cells[a]);
n=StrToFloat(StringGrid2->Cells[l][a]);
s=s+m*n;
StringGrid3->Cells[a][b]=s;
}
}
}
}
//---------------------------------------------------------------------------



[b]Модератор:
Вложение удалено.
...
Рейтинг: 0 / 0
Умножение матриц
    #38655158
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Armagedon4ukНо теперь у меня другая проблема. Кажеться он неверно умножает.Что значит "кажется"? Берешь свои матрицы, перемножаешь их вручную на бумажке и сравниваешь с результатом работы программы. И таким образом узнаешь верно умножает или неверно.
И научись делать скриншоты - не нужно публиковать весь свой экран, достаточно маленькой картинки с тем что действительно нужно.
...
Рейтинг: 0 / 0
Умножение матриц
    #38655161
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Armagedon4uk,

Переименуй свои кнопки. Button1, Button2 и так далее это забавно, но совершенно не понятно.

Зачем у тебя в вычислениях три цикла? Вполне хватит двух.
Добавь проверку на размерность матриц - не всякие две матрицы можно перемножать.
Не забывай делать код "лесенкой" - будет намного удобнее читать.
...
Рейтинг: 0 / 0
Умножение матриц
    #38655284
Armagedon4uk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Неправильно умножает но только на половину(верхнюю) а вторая половина(нижняя) правильная.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
int a,b;

double s,m,n;

for(a=0;a<StringGrid1->RowCount;a++)
{

        s=0;

for(b=0;b<StringGrid1->ColCount;b++)
{
        m=StrToFloat(StringGrid1->Cells[a][b]);

        n=StrToFloat(StringGrid2->Cells[b][a]);

s=s+m*n;

StringGrid3->Cells[a][b]=s;
}
}
...
Рейтинг: 0 / 0
Умножение матриц
    #38655444
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Умножение матриц - это Лаба на 1 курсе. Ею заполонили весь интернет.
И даже если-ты не знаешь чё как можно просто скачать сорс, разрбрать
его на атомы и потом уже подпилить для себя и своих нужд.

http://www.algolib.narod.ru/Math/Matrix.html
http://msdn.microsoft.com/ru-ru/library/hh873134.aspx

Эх ты, тютя...
...
Рейтинг: 0 / 0
Умножение матриц
    #38656564
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно проблем с умножением матриц не наблюдал, меня больше интересовала реализация ввода данных. Программа ниже написана для целых чисел, ограничение идёт из-за ввода данных. И то ввод, видимо из-за буферизации не до конца корректно работает если ввести несколько символом, то он запишет нули в следующие элементы матрицы.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
//получает целое число из стандартного потока, если встречает ошибку ввода во время чтения внутри числа, 
//заканчивает чтение. Максимальная длина числа 7 символов, число знаковое.
int get_number() 
{				
	int res = 0;
	char buf[8];//буфер для хранения символов числа
	char* s_buf = buf;

	int cur;
	while ((cur = getc(stdin)) != '\n')
	{
		if (cur != ' ')//пропускаю ведущие пробелы
		{
			char isNegative = 0;
			int length = 0;//количество символов числа без знака
			
			//работа с первым символом
			if (cur == '-')//Здесь не тернанрный оператор только потому, что я не знаю как return 0 в нём использовать
			{
				isNegative = 1;
			}
			else if (cur>='0' && cur<='9')
			{
				*s_buf++ = cur;
				length++;
			}
			else 
			{
				return 0; //выход из функции, возврат 0
			}

			//работа с остальными символами
			while ((cur = getc(stdin)) != '\n' && *s_buf)
			{
				if (cur >= '0' && cur <= '9')
				{
					*s_buf++ = cur;
					length++;
				}
				else
				{
					break;//выход из while
				}
			}

			//Получаю число из массива buf и переменной isNegative
			for (int i = 1; length > 0; i *= 10)
			{
				res += (*(buf + length-1)-48)*i;//как бы уйти от '-48'
				length--;
			}
			(isNegative == 1) ? res *= -1 : false;
			
			return res;	
		}
	}
}


//matrix1
const unsigned char row1 = 3;
const unsigned char col1 = 4;
int matrix1[row1][col1];

//matrix2
const unsigned char row2 = 4;
const unsigned char col2 = 2;
int matrix2[row2][col2];

//matrix2
const unsigned char row3 = row1;
const unsigned char col3 = col2;
int res_matrix[row3][col3];

int main(int argc,char** argv)
{
	if (col1 != row2)//если число столбцов первой матрицы не равно числу строк второй матрицы
	{
		printf("Number of columns matrix1 is not equal number of rows matrix2 \n");
		return 0;
	}
	
       //Запись матриц
	printf("dimension matrix1:%i x %i \n", row1, col1);
	for (int i = 0; i < row1; i++)
	{
		for (int j = 0; j < col1; j++)
		{
			printf("matrix1[%i][%i]=", i, j);
			*((int*)matrix1 + col1*i + j) = get_number();
		}
		printf("\n");
	}
	printf("\n");
	printf("dimension matrix2:%i x %i \n", row2, col2);
	for (int i = 0; i < row2; i++)
	{
		for (int j = 0; j < col2; j++)
		{
			printf("matrix2[%i][%i]=", i, j);
			*((int*)matrix2 + col2*i + j) = get_number();
		}
		printf("\n");
	}
	printf("\n");

	//Произведение матриц
	for (int i = 0; i < row3; i++)
	{
		for (int j = 0; j < col3; j++)
		{
			res_matrix[i][j] = 0;//Нужно ли занулять, чтобы случайно не суммировать к мусору ?
			for (int s = 0; s < col1; s++)
			{
				res_matrix[i][j] +=matrix1[i][s] * matrix2[s][j];//а вот тут можно и такую индексацию применить
			}
		}
	}
	printf("\n\nMatrix_multiplication \n");
	//Результат в поток вывода
	for (int i = 0; i < row3; i++)
	{
		for (int j = 0; j < col3; j++)
		{
			printf("%i ", res_matrix[i][j]);
		}
		printf("\n");
	}

	return 0;
}
...
Рейтинг: 0 / 0
Умножение матриц
    #38657417
Armagedon4uk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SashaMercury,

Спасибо помогло. Теперь считает нормально. Но вознилка новая проблема! Когда программа умножает квадратные матрици все нормально как только матрицы не квадратные выдает ошибку
...
Рейтинг: 0 / 0
Умножение матриц
    #38658213
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Судя по скриншоту, первопричина проблемы не в размерности матриц.
...
Рейтинг: 0 / 0
Умножение матриц
    #38658258
Armagedon4uk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SashaMercury,

Тогда в чем проблема?
...
Рейтинг: 0 / 0
Умножение матриц
    #38659527
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.

Я решил создать к этому примеру функцию, getmatrix, и предъявил к ней следующие требования.

Она принимает:
1. Количество столбцов
2. Количество строк
3. Указатель на функцию, которая будет считывать данные для одного элемента. Моя get_number(выше) не идеальна, возможно я перепишу её или буду пользоваться другими функциями (вероятно уже есть стандартные). Эта функция будет возвращать тип, заранее мне неизвестный. В моём случае int, в другом случае double.

Она должна возвращать матрицу (массив n x m). На самом деле я думаю она вернёт указатель на указатель, тут я должен сам разобраться как это сделать.

Подскажите пожалуйста как реализовать пункт 3.
...
Рейтинг: 0 / 0
Умножение матриц
    #38659535
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, и функция возвращает массив неизвестного типа. Тоже возникают проблемы. Написал так, но это скорее всего ересь

Код: plaintext
1.
2.
void** get_matrix(const unsigned char count_rows, const unsigned char count_columns, void(*get_function)())
{}
...
Рейтинг: 0 / 0
Умножение матриц
    #38659541
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Передавай в параметрах указатели (или ссылки) на переменные куда сохранить результат.
...
Рейтинг: 0 / 0
Умножение матриц
    #38660226
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryvoid(*get_function)()[/SRC]
У функции на которую указывает такой указатель сигнатура такая:
Код: plaintext
1.
void get_function()


Таким образом она ничего не возвращает - т.е. бесполезна :)

Вообще этот пример неудачный для применения типа void. Тут же везде числа. Используйте double.
...
Рейтинг: 0 / 0
Умножение матриц
    #38660886
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо.
Код: plaintext
1.
2.
3.
4.
void get_matrix(double** matrix, double(*get_function)())
{
	
}



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

Но как мне узнать какая длина одной строки ? Передавать ещё один параметр ?

Вот так например, всё окей
Код: plaintext
1.
2.
3.
4.
void get_matrix(double matrix[][5], double(*get_function)())
{
	
}


Но я хочу чтобы функция принимала любую матрицу. Так нельзя:

Код: plaintext
1.
2.
3.
4.
void get_matrix(double matrix[][char count_column], double(*get_function)())
{
	
}
...
Рейтинг: 0 / 0
Умножение матриц
    #38661943
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но как мне узнать какая длина одной строки ? Передавать ещё один параметр ?

А почему бы и нет ?

Или сделай класс "Матрица", эти все параметры будут внутри этого объекта.
...
Рейтинг: 0 / 0
Умножение матриц
    #38662103
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Написал вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
void set_matrix(double** matrix, int count_column, double(*get_function)())
{
	int count_row = sizeof(matrix) / (sizeof(double)*count_column);
	for (int i = 0; i < count_row; i++)
	{
		for (int j = 0; j < count_column; j++)
		{
			*((double*)matrix + i*count_column + j) = get_function();
		}
	}
}



Но так нельзя, потому что функция не понимает что я передаю двухмерный массив, она возможно думает что я передаю указатель на указатель, и когда я её вызываю
Код: plaintext
1.
2.
	double a[10][10];
	set_matrix(a, 10,(double)get_number);



она ругается. И ещё ругается на преобразование, так делать вероятно нельзя. Потому я испрашивал про то как указать функцию с неизвестным типом
...
Рейтинг: 0 / 0
Умножение матриц
    #38662107
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
double** matrix
sizeof(matrix)


Это не работает так как вы хотите. Тут вычисляется размер самого указателя. Размер переданного массива стандартными средствами вычислить нельзя.

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
double get_number(void)
{
...
}

void set_matrix(double* matrix, int count_row, int count_column, double(*get_function)(void))
{
	for (int i = 0; i < count_row; i++)
	{
		for (int j = 0; j < count_column; j++)
		{
  			matrix[i*count_column + j] = get_function();
 		}
	}
}

{
	double a[10][12];
	set_matrix(&a[0][0], 10, 12, get_number);
}
...
Рейтинг: 0 / 0
Умножение матриц
    #38662117
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте :)
Anatoly Moskovsky, до того что нужно передавать адрес первого элемента и количество столбцов и строк до меня дошло за это время самостоятельно, честно :)

Но с функцией не получается. Ругается.
Вот функция:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
void set_matrix(double* matrix, int count_column, int count_row, double(*get_function)(void))
{
	for (int i = 0; i < count_row; i++)
	{
		for (int j = 0; j < count_column; j++)
		{
			*((double*)matrix + i*count_column + j) = 1;
		}
	}
}



А это её вызов
Код: plaintext
1.
set_matrix(&a[0][0],10,10,get_number);



Ниже get_number:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
int get_number(void) 
{				
	int res = 0;
	char buf[8];//буфер для хранения символов числа
	char* s_buf = buf;

	int cur;
	while ((cur = getc(stdin)) != '\n')
	{
		if (cur != ' ')//пропускаю ведущие пробелы
		{
			char isNegative = 0;
			int length = 0;//количество символов числа без знака
			
			//работа с первым символом
			if (cur == '-')//Здесь не тернанрный оператор только потому, что я не знаю как return 0 в нём использовать
			{
				isNegative = 1;
			}
			else if (cur>='0' && cur<='9')
			{
				*s_buf++ = cur;
				length++;
			}
			else 
			{
				return 0; //выход из функции, возврат 0
			}

			//работа с остальными символами
			while ((cur = getc(stdin)) != '\n' && *s_buf)
			{
				if (cur >= '0' && cur <= '9')
				{
					*s_buf++ = cur;
					length++;
				}
				else
				{
					break;//выход из while
				}
			}

			//Получаю число из массива buf и переменной isNegative
			for (int i = 1; length > 0; i *= 10)
			{
				res += (*(buf + length-1)-48)*i;//как бы уйти от '-48'
				length--;
			}
			(isNegative == 1) ? res *= -1 : false;
			
			return res;	
		}
	}
}



Она возвращает int, а функция set_matrix принимает функцию возвращающую double. Собственно на это компилятор и ругается при попытке её вызвать
...
Рейтинг: 0 / 0
Умножение матриц
    #38662460
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
			//Получаю число из массива buf и переменной isNegative
			for (int i = 1; length > 0; i *= 10)
			{
				res += (*(buf + length-1)-48)*i;//как бы уйти от '-48'
				length--;
			}
			(isNegative == 1) ? res *= -1 : false;
			return res;	



Несколько наблюдений.

Ты как-то уж очень причудливо описал цикл for(..). Итерационное выражение i*=10 а проверка идёт по length > 0.
Такой код трудно сопровождать и вносить изменения. Уж лучше-бы сделал через while(...). Тогда для двух итерационных
выражений появится "смысл" когда они стоят рядом.

От -48 скорее всего не уйти никак. Это смещение в кодовой странице. И его нужно вычислить до или после. Или работать
со своей виртуальной кодовой страницей где первая десятка совпадает с кодом символов.

Иногда цикл улучшается если его перевернуть наоборот.

И вообще странно зачем писать свой аналог atoi.
...
Рейтинг: 0 / 0
Умножение матриц
    #38662494
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury
Код: plaintext
1.
				res += (*(buf + length-1)-48)*i;//как бы уйти от '-48'


Пиши '0' будет читабельнее.

преобразование строки в число проще делается
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
int str2int(const char *buf)
{
	int res = 0;
	bool is_negative = false;
	while(buf) {
		if(*buf >= '0' && *buf <= '9') {
			res = res * 10 + *buf - '0';
		} else if(*buf == '-' && res == 0) {
			is_negative = true;
		} else if(*buf != ' ' || res != 0 || is_negative) {
			break;
		}
		buf++;
	}
	if(is_negative) {
		return -res;
	} else {
		return res;
	}
}

...
Рейтинг: 0 / 0
Умножение матриц
    #38662501
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryОна возвращает int, а функция set_matrix принимает функцию возвращающую double. Собственно на это компилятор и ругается при попытке её вызвать
Сделай функцию-обертку и давай ее:
Код: plaintext
1.
2.
3.
4.
double get_number_double(void) 
{
  return get_number(); 
}
...
Рейтинг: 0 / 0
Умножение матриц
    #38662563
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

Зачем обертки? Изначально double возращать :)
...
Рейтинг: 0 / 0
Умножение матриц
    #38662588
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonИ вообще странно зачем писать свой аналог atoi.
Тут даже не atoi нужен, а просто scanf и читать сразу в double.
...
Рейтинг: 0 / 0
Умножение матриц
    #38662679
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskymaytonИ вообще странно зачем писать свой аналог atoi.
Тут даже не atoi нужен, а просто scanf и читать сразу в double.
Может лучше atof тогда?
...
Рейтинг: 0 / 0
Умножение матриц
    #38662705
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonAnatoly MoskovskyТут даже не atoi нужен, а просто scanf и читать сразу в double.
Может лучше atof тогда?
Он там читает из stdin.
Незачем читать в строку, потом преобразовывать, когда можно сразу в число считать.
...
Рейтинг: 0 / 0
Умножение матриц
    #38662717
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да. ОК.
...
Рейтинг: 0 / 0
Умножение матриц
    #38663112
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо :)

Dima_T
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
int str2int(const char *buf)
{
	int res = 0;
	bool is_negative = false;
	while(buf) {
		if(*buf >= '0' && *buf <= '9') {
			res = res * 10 + *buf - '0';
		} else if(*buf == '-' && res == 0) {
			is_negative = true;
		} else if(*buf != ' ' || res != 0 || is_negative) {
			break;
		}
		buf++;
	}
	if(is_negative) {
		return -res;
	} else {
		return res;
	}
}



Всё-же мне кажется что лучше выделить отдельно проверку первого НЕпробела. Это будет быстрее, и код будет более читабельный. Но то что вы не сохраняете в отдельный буфер символы, очевидное преимущество. Я плохо подумал над алгоритмом. Немного переделал согласно вашему комментарию:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
//Данная функция аналогична get_number. Корректировки от Dima_T
double get_number2(void)
{
	double res = 0;

	int cur;
	while ((cur = getc(stdin)) != '\n')
	{
		if (cur != ' ')//пропускаю ведущие пробелы
		{
			char isNegative = 0;
			//работа с первым символом
			if (cur == '-')
			{
				isNegative = 1;
			}
			else if (cur >= '0' && cur <= '9')
			{
				res = cur - '0';
			}
			else
			{
				return 0; //выход из функции, возврат 0
			}

			//работа с остальными символами
			while ((cur = getc(stdin)) != '\n')
			{
				if (cur >= '0' && cur <= '9')
				{
					res = 10 * res + cur - '0';
				}
				else
				{
					break;//выход из while
				}
			}
			return (isNegative == 1) ? -res:res;
		}
	}
}



maytonИ вообще странно зачем писать свой аналог atoi.


я забыл про эту функцию, и мне было самому интересно реализовать :)
...
Рейтинг: 0 / 0
Умножение матриц
    #38663113
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С вводом покончено. Сейчас напишу отдельную функцию для произведения матриц, и например для вычисления детерминанта и обратной матрицы. А можно мне хранить все функции эти в структуре например ?
...
Рейтинг: 0 / 0
Умножение матриц
    #38663122
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я знаю что с С++ есть классы, и скорее всего для этого они и нужны. А на Си как сгруппировать эти функции ?
...
Рейтинг: 0 / 0
Умножение матриц
    #38663123
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Делал сейчас умножение:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
double* matrix_multiplication(double* m1, int row1, int col1, double* m2, int row2, int col2)
{
	if (col1 != row2)
	{
		printf("col1!=row2 \n");
		return 0;
	}
	//double res[row1][col2];
}



Закомментированная строчка очевидно некорректна, тк неизвестно сколько памяти выделять. Какая сигнатура должна быть у данной функции в рамках языка С ?
...
Рейтинг: 0 / 0
Умножение матриц
    #38663128
Armagedon4uk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А мне так никто не помог. Печально :(
...
Рейтинг: 0 / 0
Умножение матриц
    #38663200
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Armagedon4uk, чем тебе должен помогать форум С++ ? В твоём коде есть ошибка.
С нашей точки зрения она видна как попытка прочитать числовое значение из пустой ячейки.
Почему ты лезешь в пустую ячейку - чёрт его знает. Наверное неправильный алгоритм.
...
Рейтинг: 0 / 0
Умножение матриц
    #38664009
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryЗакомментированная строчка очевидно некорректна, тк неизвестно сколько памяти выделять. Какая сигнатура должна быть у данной функции в рамках языка С ?
double *res = malloc( sizeof(double) * row1 * col1);
...
Рейтинг: 0 / 0
Умножение матриц
    #38664876
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо. Прочитал про неё в стандарте, разобрался в целом. Вот функция
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
//Произведение двух матриц
double* matrix_multiplication(double* m1, int row1, int col1, double* m2, int row2, int col2)
{
	if (col1 != row2)
	{
		printf("row1!=col2 \n");
		return 0;
	}
	double* res = (double*)malloc(sizeof(double)*col1*row2); //выделяю память на хранение элментов матрицы произведения
	for (int i = 0; i < row1; i++)
	{
		for (int j = 0; j < col2; j++)
		{
			*(res + i*col2 + j) = 0;//зануляю перед использованием
			for (int s = 0; s < col1; s++)
			{
				*(res + i*col2 + j) += (*(m1 + i*col1 + s)) * (*(m2 + s*col2 + j));
			}
		}
	}
	printf("\n");
	//вывод матрицы на экран
	view_matrix(res, row1, col2);
	return res;
}



1. Функция void malloc(size_t size) возвращает void, и мне необходимо явное приведение к (double*). Вы в своём примере этого не сделали. Или дело в компиляторе ?
2. Обратите внимание, я делаю вывод на экран внутри функции. Понятно почему, я возвращаю только указатель на начало, нет размерности. Потому я пришёл к выводу: нужно создать структуру Матрица, и возвращать указатель на элемент данной структуры.Это верно ?
...
Рейтинг: 0 / 0
Умножение матриц
    #38664889
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
3. При объявлении переменных/массивов(да и вообще любых операций связанных с выделением памяти) скорее всего так-же происходит неявный вызов malloc ?
...
Рейтинг: 0 / 0
Умножение матриц
    #38664890
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
От объявления зависит.
...
Рейтинг: 0 / 0
Умножение матриц
    #38664894
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury1. Функция void malloc(size_t size) возвращает void, и мне необходимо явное приведение к (double*). Вы в своём примере этого не сделали. Или дело в компиляторе ?
надо приводить
Код: plaintext
1.
double *res = (double *)malloc( sizeof(double) * row1 * col1);


и по окончании не забыть освободить память
Код: plaintext
1.
free(res);


SashaMercury2. Обратите внимание, я делаю вывод на экран внутри функции. Понятно почему, я возвращаю только указатель на начало, нет размерности. Потому я пришёл к выводу: нужно создать структуру Матрица, и возвращать указатель на элемент данной структуры.Это верно ?
Можно отдельно размерность вернуть, но удобнее структуру сделать
...
Рейтинг: 0 / 0
Умножение матриц
    #38665590
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury3. При объявлении переменных/массивов(да и вообще любых операций связанных с выделением памяти) скорее всего так-же происходит неявный вызов malloc ?Нет.
Объявление переменных идет либо на стеке (локальные) либо в сегменте данных (глобальные). А память выделяемая через malloc находится на куче.
Автоматически на куче ничего не выделяется. Хотя если ты сделаешь функцию типа твоей последней, запихнешь ее в какую-то библиотеку, то можно будет говорить "при вызове этой функции неявно вызывается malloc".
На самом деле есть много таких библиотечных функций, у них в документации всегда явно будет упомянуто что функция выделяет память которую потом надо будет вручную освободить.


Dima TSashaMercury1. Функция void malloc(size_t size) возвращает void, и мне необходимо явное приведение к (double*). Вы в своём примере этого не сделали. Или дело в компиляторе ?
надо приводить
Код: plaintext
1.
double *res = (double *)malloc( sizeof(double) * row1 * col1);


В С приводить не нужно. В С++ нужно.
Приведение void* в любой другой ссылочный тип в C идет автоматом (и обратно тоже).

Dima Tи по окончании не забыть освободить память
Код: plaintext
1.
free(res);

Это не обязательно, зависит от задачи.
...
Рейтинг: 0 / 0
Умножение матриц
    #38665799
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, вот оно в чём дело. То есть дело в языке.
Но если я освобожу память внутри функции, я не смогу по выходу из неё использовать значения полученные внутри функции. При завершении процесса программы вся запрошенная память освободится автоматически ?
Сегодня создам структуру, и перепишу всё что сделал ранее.
...
Рейтинг: 0 / 0
Умножение матриц
    #38665827
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПри завершении процесса программы вся запрошенная память освободится автоматически ?"А ты угадай" (ц) бандюган из х/ф "Бедная Саша".
...
Рейтинг: 0 / 0
Умножение матриц
    #38665832
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryПри завершении процесса программы вся запрошенная память освободится автоматически ?
Зависит от платформы.
Есть платформы, на которых у всех процессов общая память. Там завершение процесса не всегда освобождает память.
К счастью вероятность встретиться с такими платформами стремится к нулю :)
...
Рейтинг: 0 / 0
Умножение матриц
    #38665846
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryНо если я освобожу память внутри функции, я не смогу по выходу из неё использовать значения полученные внутри функции.
Освобождать надо когда память уже не нужна, а где - без разницы. free() получает конкретный адрес, по которому была выделена память, а из какой переменной он взят - без разницы.
...
Рейтинг: 0 / 0
Умножение матриц
    #38666676
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 10.06.2014 02:40, SashaMercury wrote:

> Но если я освобожу память внутри функции, я не смогу по выходу из неё
> использовать значения полученные внутри функции.

Нет, конечно же нет.

При завершении процесса
> программы вся запрошенная память освободится автоматически ?

Как правило, да.

Но надеяться на это нельзя, и стандарты языков (ни С, ни С++) это не
гарантируют. Существуют операционные системы, где память по окончании
процесса не освобождается автоматически, яркий пример -- MS DOS и её
аналоги.



Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Умножение матриц
    #38667055
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хочу хранить все элементы матрицы в структуре. Пытался так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
struct matrix
{
	unsigned char row;
	unsigned char column;
	double* s = (double*)malloc(sizeof(double)*row*column);
	double determinant;
};



Но судя по всему у меня ничего не получилось, проверил вот так:
Код: plaintext
1.
2.
3.
4.
5.
	matrix a;
	printf("%i %i \n \n", sizeof(a), sizeof(a.s));
	a.column = 3;
	a.row = 3;
	printf("%i %i \n \n", sizeof(a), sizeof(a.s));



Можно ли хранить в структуре матрицу так как я хочу?

Можно сделать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
struct matrix
{
	unsigned char row;
	unsigned char column;
	//double* s = (double*)malloc(sizeof(double)*row*column);
	double determinant;
	double mat[];
};



И хранить матрицу в mat. Только я не понял как мне выделить на mat память в размерер double*row*column.

Подскажите как решить данную проблему, если это возможно.
...
Рейтинг: 0 / 0
Умножение матриц
    #38671895
pirovindos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Например (если С++), выделять память в конструкторе, параметрами которого будут нужные row и column.
...
Рейтинг: 0 / 0
Умножение матриц
    #38671930
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury, в С++ стиле классикой жанра является определение класса Матрицы, перегрузка
четырех операций, операции '=' и конструктора копирования. Этим мучают студентов обычно
...
Рейтинг: 0 / 0
Умножение матриц
    #38672462
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.
Я ещё не знаю Си. Потому мне рано изучать С++.

Нужно решить эту классическую задачу в рамках Си
...
Рейтинг: 0 / 0
Умножение матриц
    #38672480
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercury,

Это все равно что сказать -
Я ещё не научился ездить на автомобиле. Потому мне рано летать самолетами.
Нужно решить эту классическую задачу поездки на Карибы в рамках езды на автомобиле
...
Рейтинг: 0 / 0
Умножение матриц
    #38672484
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну С так С.

Вот схематично как это решается.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
struct matrix 
{
	int rows;
	int cols;
	double* data;
};

struct matrix* create_matrix(int rows, int cols)
{
	struct matrix* m = malloc(sizeof(struct matrix));
	m->rows = rows;
	m->cols = cols;
	m->data = malloc(rows * cols * sizeof(*data));
	return m;
}

void destroy_matrix(struct matrix* m)
{
	free(m->data);
	free(m);
}

double matrix_get(struct matrix* m, int row, int col)
{
	return m->data[m->cols * row + col];
}

void matrix_set(struct matrix* m, int row, int col, double val)
{
	m->data[m->cols * row + col] = val;
}

struct matrix* multiply_matrix(struct matrix* m1, struct matrix* m2)
{
	struct matrix* result = create_matrix(....);
	...
	// умножаем -  берем ячейки из m1 и m2 с помощью matrix_get,
	// записываем рез-т в ячейки result с помощью matrix_set
	
	return result;
}

int main()
{
	struct matrix* m1 = create_matrix(....);
	struct matrix* m2 = create_matrix(....);
	struct matrix* res;

	// заполняем m1 и m2
	
	// перемножаем
	res = multiply_matrix(m1, m2);
	
	// читаем результат
	
	// удаляем объекты
	destroy_matrix(m1);
	destroy_matrix(m2);
	destroy_matrix(res);
	
}



Опционально, функции get/set можно объявить inline чтобы минимизировать оверхед от вызова функции при обращениях к ячейкам, как наиболее частой операции.
Но поскольку задача учебная в этой оптимизации нет смысла.
...
Рейтинг: 0 / 0
Умножение матриц
    #38674852
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, спасибо :)
Меня собственно интересовал вопрос с выделением памяти для массива внутри структуры.

Код: plaintext
1.
2.
3.
4.
5.
void destroy_matrix(struct matrix* m)
{
	free(m->data);
	free(m);
}



Странно, я думал что если освобождаю память для матрицы, то я освобождаю память для всех связанных с ней элементов.
...
Рейтинг: 0 / 0
Умножение матриц
    #38674857
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryСтранно, я думал что если освобождаю память для матрицы, то я освобождаю память для всех связанных с ней элементов.
Нет. В С такое невозможно. Тут все ручками.
В С++ возможно при использовании классов (например контейнеров стандартной библиотеки).
...
Рейтинг: 0 / 0
Умножение матриц
    #38675209
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyОпционально, функции get/set можно объявить inline чтобы минимизировать оверхед от вызова функции при обращениях к ячейкам, как наиболее частой операцииАнатолий, а что, в С теперь и inline есть?
...
Рейтинг: 0 / 0
Умножение матриц
    #38675213
pirovindos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryСтранно, я думал что если освобождаю память для матрицы, то я освобождаю память для всех связанных с ней элементов.

Здесь, грубо говоря, такой принцип: на каждое выделение памяти, должно быть освобождение. Посмотри в create_matrix - malloc два раза вызывается.
...
Рейтинг: 0 / 0
Умножение матриц
    #38675449
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychАнатолий, а что, в С теперь и inline есть?
Начиная с C99 официально.
А GCC умел давно.
...
Рейтинг: 0 / 0
Умножение матриц
    #38675593
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyegorychАнатолий, а что, в С теперь и inline есть?
Начиная с C99 официально.
А GCC умел давно.ясно, спасибо, давно я не писал на чистом С, оказывается ))
...
Рейтинг: 0 / 0
Умножение матриц
    #38765262
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryAnatoly Moskovsky, спасибо :)

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

В С ?
Как бы это супернаивно.
В С ничего не делается автоматом.
...
Рейтинг: 0 / 0
Умножение матриц
    #38765582
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это хорошо :)
...
Рейтинг: 0 / 0
Умножение матриц
    #38765846
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не то слово.
...
Рейтинг: 0 / 0
62 сообщений из 62, показаны все 3 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Умножение матриц
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]