C noob, случайное создание матричной структуры - PullRequest
0 голосов
/ 31 октября 2011

Я пытаюсь создать структуру, генерирующую случайную матрицу и получающую атрибут «ошибка: ожидается: â, â, â, â, â; â, âasmâ или â_ _â перед« матрицей » компилирование. Как я могу заставить это работать эффективно и продуктивно?

Я предполагаю, что ожидаемые ошибки обычно вызваны опечатками, но я не вижу никаких.

Я очень плохо знаком с C, поэтому указатели и malloc для меня совершенно чужды. Я очень ценю вашу помощь.

/* It's called RandomMatrixMaker.c */

#include <stdio.h>
#include <stdlib.h>

typdef struct {
  char* name;
  int MID;
  int MRows;
  int MCols;
  long[][]* MSpace;
} matrix;

matrix makeRIDMatrix(char* name, int MID, int MRows, int MCols) {
  matrix m;
  static int i, j, r;
  m.name = name;
  m.MID = MID;
  m.MRows = MRows;
  m.MCols = MCols;
  for (i=0; i<m.MRows; i++) {
    for (j=0; i<m.MCols; j++) {
      r = random(101);
      *(m.MSpace[i][j]) = r; 
    }
  }
  return m;
}

int main(void) {
  makeRIDMatrix("test", 1, 10, 10);
  return 0;
}

Ответы [ 3 ]

4 голосов
/ 31 октября 2011

Это действительно опечатка. Вы ошиблись typedef:

typdef struct {

должно быть:

typedef struct {

EDIT:

Кроме того, здесь нет смысла использовать static:

static int i, j, r;

Вы можете просто избавиться от модификатора static.

int i, j, r;
2 голосов
/ 31 октября 2011

Как уже упоминалось в другом постере, есть опечатка, но даже после исправления она не будет компилироваться из-за определения matrix.MSpace.

Давайте начнем с makeRIDMatrix ().Вы объявили автоматическую (стековую) переменную типа «матрица».В конце функции вы возвращаете этот объект.Хотя это допустимо, это не рекомендуется.Если структура большая, вы будете копировать много данных без необходимости.Лучше передать указатель на матрицу в makeRIDMatrix () и сделать makeRIDMatrix () заполнить содержимое.

Тест во внутреннем цикле против i, но должен быть против j.

Далее давайте посмотрим на определение «матрица».Определение «MSpace» является беспорядком и даже не скомпилируется.Даже если это произойдет, поскольку вы не определили длину строки, компилятор не сможет рассчитать смещение для любого данного элемента в массиве.Вам нужен двумерный массив без указания длины строки, но вы не можете сделать это в C. Вы можете сделать это на других языках, но не на C.

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

C - это не Java.

(Это также не один из интерпретируемых языков, таких как JavaScript, PHP, Python, Ruby и т. Д.)

Вы не получаете динамически расширяемые массивы;вы не получаете автоматическое распределение памяти;вы не получаете сборщик мусора из не привязанной памяти.

Вам нужно что-то вроде этого:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct {
  char* name;
  int MID;
  unsigned int MRows;
  unsigned int MCols;
  long *MSpace;
} matrix;

void makeRIDMatrix(matrix *pmx, char* name, int MID,
                   unsigned int MRows, unsigned int MCols) {
  int i, j;
  long *MSpace = malloc(sizeof(*MSpace)*MRows*MCols);
  if (MSpace == NULL) {
    return;
  }
  pmx->name = name;
  pmx->MID = MID;
  pmx->MRows = MRows;
  pmx->MCols = MCols;
  pmx->MSpace = MSpace;

  srandom((unsigned int)time(NULL));
  for (i=0; i<MRows; i++) {
    for (j=0; i<MCols; j++) {
      long int r = random() % 101L;
      *(MSpace++) = r;
    }
  }
}

inline long * item_addr(const matrix *pmx, 
                        unsigned int row, unsigned int col) {
  if (pmx == NULL || pmx->MSpace == NULL
      || row >= pmx->MRows || col >= pmx->MCols) {
    return NULL;
  }
  return &(pmx->MSpace[row * pmx->MCols + col]);
}

long get_item(const matrix *pmx, unsigned int row, unsigned int col) {
  long *addr = item_addr(pmx, row, col);
  return addr == NULL ? 0L : *addr;
}

void set_item(matrix *pmx, 
              unsigned int row, unsigned int col, 
              long val) {
  long *addr = item_addr(pmx, row, col);
  if (addr != NULL) {
    *addr = val;
  }
}

int main(void) {
  matrix m;
  makeRIDMatrix(&m, "test", 1, 10, 10);
  return 0;
}

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

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

В-третьих, я изменил переменные row / cols на unsigned int - нет смысла определятьмассив с отрицательными индексами!

В-четвертых: небольшая проверка ошибок.Например, makeRIDMatrix () не знает и не заботится о том, являются ли значения параметров разумными (например, указатель матрицы не проверяется на NULLness).Это упражнение для студента.

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

1029 * Тем не менее - все это спорно?.Вам нужно найти себе хороший учебник по Си или хороший онлайн-курс и поработать с примерами.Код, который вы здесь привели, показывает, что вы пробиваете вес выше своего веса, и вам нужно развить еще несколько С-мышц, прежде чем войти в это кольцо!
1 голос
/ 31 октября 2011

Что касается вашего вопроса о «массивах переменного размера», вы можете получить что-то вроде:

/* can stick this into your struct, this is just an example */
size_t rows, cols;
long **matrix;

/* set the values of rows, cols */

/* create the "array" of rows (array of pointers to longs) */
matrix = (long**)malloc(rows * sizeof(long*));

/* create the array of columns (array of longs at each row) */
for (i = 0; i < rows; i++)
   matrix[i] = (long*)malloc(cols * sizeof(long));

/* ... */

/* free the memory at the end */
for (i = 0; i < rows; i++)
   free(matrix[i]);

free(matrix);

Тогда вы можете просто получить доступ к динамически распределенной матрице, аналогичной любому другому массиву массивов.

т. установить элемент в первой строке (строка 0) и четвертом столбце (столбец 3) в 5:

matrix[0][3] = 5;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...