wikiabhishek Ответов: 3

напишите код для разреженной матрицы на языке Си


здесь я даю некоторый код bt во время компиляции я столкнулся с 4 ошибками компиляции ....может быть, вы мне объясните, пожалуйста ???


#include <stdio.h>
#include <conio.h>
void main()
{
int r,c,i,j;
int x[100][100];
void sparse(int x[][],int r,int c);
printf("Enter the no of rows :");
scanf("%d",&r);
printf("Enter the no of columns :");
scanf("%d",&c);

for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",&x[i][j]);
}
}
sparse(x,r,c);
getch();
}
void sparse(int x[][],int r,int c)
{
int sp[200][200];
int m,n,k=1;
for(m=0;m<r;m++)
{
for(n=0;n<c;n++)
{
if(x[m][n]!=0)
{
sp[k][0]=m+1;
sp[k][1]=n+1;
sp[k][2]=x[m][n];
k++;
}
}
}
sp[0][0]=r;
sp[0][1]=c;
sp[0][2]=k-1;

printf("The sparse matrix is :\n");
for(m=0;m<k;m++)
{
for(n=0;n<3;n++)
{
printf("%d\t",sp[m][n]);
}
}
}

[no name]

Как вы думаете, может быть, это поможет нам, если вы скажете нам, в чем заключаются ошибки?

wikiabhishek

ошибки-это "размер типа 'int[]' неизвестен или равен нулю " ....что это значит???

[no name]

Оно означает именно то, что говорит. Вы пытаетесь создать массив int и не сообщили компилятору количество элементов, которые будут иметь массив.

H.Brydon

Позвольте мне только кратко вмешаться. Ни одно из решений № 1, 2 или 3 не является реализацией разреженного массива. Если это домашнее задание или фактически иное обязательное требование, вы получите "ноль" (или эквив) за решения. Я бы предложил подружиться с Google и спросить его, что такое разреженный массив. Попробуйте попросить "разреженный массив c" или что-то подобное...

3 Ответов

Рейтинг:
2

Andreas Gieriet

Определите аргументы следующим образом int**x вместо int x[][].

[РЕДАКТИРОВАТЬ]
Вышеизложенного недостаточно, как показано в решении № 2.
С (многомерными) массивами вы должны пройти по крайней мере все измерения, кроме первого (вы также можете пройти первое, конечно). Или вы выполняете вычисление положения элемента явно.

C/C++ требует знать все (кроме первого) измерения для вычисления конкретного элемента. Причина: многомерные массивы хранятся в одном блоке памяти, где доступ к каждому элементу осуществляется путем вычисления соответствующей позиции в этом блоке памяти: pos = ...((((idx0) * dim1 + idx1) * dim2 + idx2) * ... + ...) ....

В вашем случае
- idx0: 0...99
- поля dim1: 100
- idx1: 0...99
(*нет* высшее измерение и показатели 2,3,4...)

Ниже приведены идентичные результаты, предполагающие, что вы передаете правильные аргументы в вызове функции:

неявный явный
void sparse(int x[][100], int rows, int cols)
{
   for(int m = 0; m < rows; ++m)
   {
       for(int n = 0; n < cols; ++n)
       { 
           ...

           int v = x[m][n];
           ...
       }
   }
}
void sparse(int **x, int rows, int cols)
{
   for(int m = 0; m < rows; ++m)
   {
       for(int n = 0; n < cols; ++n)
       { 
           ...
           int *first_elem = *x;
           int v = first_elem[m*cols+n];
           ...
       }
   }
}


[/РЕДАКТИРОВАТЬ]

Овации
Энди


H.Brydon

У вас есть правильная идея, но это не создает разреженный массив.

Andreas Gieriet

ОП действительно имел это в названии, но конкретный вопрос касается ошибки компилятора. Пожалуйста, прочтите вопрос тщательно перед голосованием вниз... (Я предполагаю, что это вы голосовали против) ;-)
Овации
Энди

H.Brydon

(Я не стал понижать голос). Я считал, что название этой страницы является частью проблемы. Действительно, он/она не упоминал о скудости в тексте, но ИМХО это кажется важным.

Andreas Gieriet

Да, название и вопрос не совпадают. Таким образом, каждый выбирает тот, который выглядит более важным...
Овации
Энди
PS: и мое решение действительно не является полным ответом на вопрос об "ошибке компилятора".
ППС: в *название* вопрос по Google производит хорошее транспортное сообщение: с++ разреженный массив.
PPPS: Извините, что предположил, что вы отрицаете решение - мои извинения.

Рейтинг:
10

Mike M.00

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

С точки зрения компьютера, самая большая проблема заключается в том, что компьютер не знает, насколько велик массив "x", когда вы передаете его в процедуру " sparse ()".

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

myArray[2][3]
будет иметь две строки по 3 значения в каждой. Допустим, первая строка массива содержит значения 1, 2 и 3, а вторая строка-значения 4, 5 и 6. В этом случае память внутри компьютера будет выглядеть следующим образом: 1, 2, 3, 4, 5, 6.

Когда мы пишем такое выражение, как
int sample = myArray[1][2];
компилятор должен вычислить правильный адрес памяти из заданных координат, используя свои знания о размере массива. В этом случае компилятор знает, что каждая строка имеет длину 3, поэтому доступ к ячейке памяти осуществляется следующим образом: 1 * 3 + 2, или 5-я ячейка памяти в памяти для массива. (Не забывайте, что массивы основаны на нуле, то есть первая строка-это строка с нулевым номером.) Таким образом, в этом примере "образец" будет установлен на 5.

Теперь мы подходим к основной проблеме, с точки зрения компьютера, в вашем коде: поскольку вы не сказали компилятору в своем определении 'sparse ()', насколько велик массив, компилятор не может знать, какую математику он должен сделать, чтобы вычислить адреса каждого элемента массива.

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

Если это просто быстрая тестовая программа, и ее не нужно будет поддерживать в будущем, самое простое решение-сделать массив " x "глобальным, поместив его вне строки" main ()", а затем вообще не передавая его в процедуру " sparse ()".

Есть и другие проблемы с вашим кодом, например, кажется, что sp [] [], который вы определяете с 200 строками по 200 столбцов, никогда не будет иметь больше, чем первые 3 столбца, используемых. А с точки зрения удобочитаемости мое личное правило-никогда не использовать однобуквенные переменные, потому что их трудно понять, каково их значение.

Во всяком случае, я надеюсь, что моя болтовня будет поучительной, хотя я оставил вам многое для продолжения отладки. Ниже приведена версия вашего кода, с отступом для удобства чтения, с "x", сделанным глобальным, чтобы " sparse()" мог его использовать.
#include <stdio.h>
#include <conio.h>

int x[100][100];

void main()
{
	int r,c,i,j;
	void sparse(int r,int c);
	printf("Enter the no of rows :");
	scanf("%d",&r);
	printf("Enter the no of columns :");
	scanf("%d",&c);
 
	for(i=0;i<r;i++)>
	{
		for(j=0;j<c;j++)>
		{
			scanf("%d",&x[i][j]);
		}
	}
	sparse(r,c);
	getch();
}
void sparse(int r,int c)
{
	int sp[200][200];
	int m,n,k=1;
	for(m=0;m<r;m++)>
	{
		for(n=0;n<c;n++)>
		{
			if(x[m][n]!=0)
			{
				sp[k][0]=m+1;
				sp[k][1]=n+1;
				sp[k][2]=x[m][n];
				k++;
			}
		}
	}
	sp[0][0]=r;
	sp[0][1]=c;
	sp[0][2]=k-1;
	 
	printf("The sparse matrix is :\n");
	for(m=0;m<k;m++)>
	{
		for(n=0;n<3;n++)
		{
			printf("%d\t",sp[m][n]);
		}
	}
}


H.Brydon

Интересное решение, но это полностью заполненный массив, а не разреженный массив.

Рейтинг:
1

TRK3

Компилятор не может сгенерировать код для выражения x[m][n], если он не знает, какого размера столбцы.

Выражение x[m][n] на самом деле является просто синтаксическим сахаром для:

*( x + m * colsize + n )


Вам нужно изменить объявление функции на:

пустота разреженной( инт **Парр, инт р с инт)

и замените все ссылки на x[m][n] на:

*(pArr + m * c + n)


H.Brydon

Это не создает разреженный массив.

TRK3

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