#c #matrix #vector #multiplication
#c #матрица #вектор #умножение
Вопрос:
Я пытаюсь умножить большую и случайную матрицу (NxN) и случайный вектор (N), используя указатели. Почему я получаю сообщение об ошибке типа «недопустимые операнды на двоичные * (имеют ‘double *’ и ‘double *’)»? Ошибка, похоже, в ptr3 [i] [j] = ptr3 [i] ptr1 [i] * ptr2 [k]; но я не могу понять, почему это не работает. Я новичок в C, поэтому я все еще не очень хорошо понимаю указатели.
int main ()
{
time_t t;
double **ptr1, **ptr2, **ptr3;
int i, j, k;
int N = 500;
ptr1 = (double **) malloc (sizeof (double *) * N);
ptr2 = (double **) malloc (sizeof (double *) * N);
ptr3 = (double **) malloc (sizeof (double *) * N);
for (i = 0; i < N; i )
ptr1[i] = (double *) malloc (sizeof (double) * N);
for (i = 0; i < N; i )
ptr2[i] = (double *) malloc (sizeof (double) * N);
for (i = 0; i < N; i )
ptr3[i] = (double *) malloc (sizeof (double) * N);
for (i = 0; i < N; i ) {
for (j = 0; j < N; j ) {
ptr1[i][j] = rand ();
}
}
for (i = 0; i < N; i ) {
*ptr2[i] = rand ();
}
t = clock();
for (i = 0; i < N; i ) {
ptr3[i] = 0;
for (k = 0; k < N; k )
ptr3[i] = ptr3[i] ptr1[i][k] * ptr2[k];
}
t = clock() - t;
double time_taken = ((double)t)/CLOCKS_PER_SEC;
printf("Tempo: %f segundos n", time_taken);
printf ("n");
return (0);
} ```
Комментарии:
1. Как говорится в сообщении: in
ptr3[i][j] = ptr3[i] ptr1[i] * ptr2[k];
— этоptr3[i][j]
double
значение, но остальные три являются указателями, и их добавление / умножение не имеет смысла.2. Также обратите внимание, что вы создали
ptr2
2D-массив, подобныйptr1
andptr3
, а не 1D-массив, упомянутый в описании и инициализированный в цикле.3. Похоже, что опубликованный код изменяется без комментариев.
4. Это похоже на вопрос «зыбучий песок». Пожалуйста, скопируйте / вставьте ваш фактический код и оставьте его, чтобы комментарии и ответы оставались актуальными.
Ответ №1:
Что говорит компилятор , так это то , что в операторе ptr3[i] = ptr3[i] ptr1[i] * ptr2[k];
бит , который говорит ptr1[i] * ptr2[k]
, пытается переключиться *
между двумя выражениями , которые имеют тип double*
. Другими словами, вам не разрешается умножать два указателя вместе. Чтобы сделать это правильно, вам нужно снова выполнить разыменование ( [i]
и [k]
уже разыменовывают double**
на a double*
). Чтобы заставить это скомпилироваться, это утверждение должно быть (я добавил круглые скобки для ясности — на самом деле они не нужны):
*ptr3[i] = (*ptr3[i]) (*ptr1[i]) * (*ptr2[k]);
Это должно привести вас к компиляции, но следующая проблема, с которой вы столкнетесь, — ошибка сегментации. На две строки выше места, где вы выполняете умножение, у вас есть это:
ptr3[i] = 0;
Это присваивается ptr3[i]
нулевому указателю, который такой же, как 0
в C (другие языки имеют другое имя этого значения: null
, None
, и т.д.). Я думаю, вы хотели сделать вот что:
*ptr3[i] = 0;
Кроме того, поскольку N
это известное фиксированное значение, вы можете отказаться от всего malloc
этого, просто сказав:
const int N = 500;
double ptr1[N][N];
double ptr2[N][N];
// ... and so on ...
Это объявление ptr1
в виде массива вместо указателя, который идентичен указателю с точки зрения шаблонов доступа к памяти, но отличается несколькими способами. В зависимости от того, что вы пытаетесь изучить, отказ от работы с динамической памятью (с использованием malloc
и free
) может пока избавить вас от небольшой головной боли.