Как бы я "породил" или создал бы несколько существ процедурно?

Когда я решил научиться программировать, я начал с Java. И хотя я знаком с написанием простого процедурного программного обеспечения (в основном на PHP), недавно я понял, что для более сложных операций я полагаюсь на объекты.

Моя первая Java-игра породила противников в случайных местах и ​​со случайными скоростями, создавая объекты. Я озадачен концепцией реализации этой процедуры в C (о которой у меня очень мало практических знаний), но я мог думать только о создании разных массивов для переменных у каждого оппонента и использовании индексов массива в качестве переменных псевдообъекта 'переменных ".

int size[50]; // opponent size
for (i = 0; i < 100; i++) {
    size[i] = random_number();
}

Есть ли простое решение, которое мой объектно-ориентированный разум упустил из виду? Или же некоторые проблемы действительно поддаются объектно-ориентированным концепциям до такой степени, что вам приходится создавать поддельные объекты (или, по крайней мере, использовать аналогичные модели)? Я все время вижу структуры в C-коде, и я знаю, что они похожи на классы по концепции, но это все, что я знаю. Поэтому мне интересно, возможно ли что-то подобное с абсолютно не объектно-ориентированным мышлением. Там нет реальной замены для создания экземпляров, не так ли? Это всего лишь распределение памяти, так что, как я понимаю, у некоторых программ на Си нет иного выбора, кроме как быть написанными с использованием той или иной формы того, что я считаю объектами.

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

Спасибо!

3 ответа

Решение

Если мы пренебрегаем всеми передовыми концепциями объектно-ориентированного программирования, такими как наследование или полиморфизм по параметрам типа, все сводится к одному и тому же.

В C++ у вас есть объекты, и вы вызываете методы, которые к ним привязаны, в C у вас есть структуры, и вы вызываете глобальные функции, передавая эти функции в качестве аргумента.

То, что я имею в виду, - это то, что принципиально важной парадигмой является концептуально иметь объекты, которые способны выполнять вещи своими методами. Теперь в C вы можете получить то же поведение, но у вас есть функции, которые не привязаны ни к какому объекту.

Так что в основном в C++ или Java вы должны иметь:

class Point {
  private:
    int x, y;
  public:
    Point(int x, int y) : x(x), y(y) { }
    void draw() { ... }
};

В чистом C вы бы имели:

struct Point {
  int x, y;
}

struct Point makePoint(int x int y) {
  struct Point p = {.x = x, .y = y};
  return p;
}

void drawPoint(struct Point p) {
  ..
}

Но семантическая сила обоих представлений по сути одинакова, хотя синтаксис различен (и даже концепция, лежащая в основе). Конечно, все изменится, если мы начнем рассматривать более мощные функции.

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

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

struct creature {
    int speed;
    int size;
};

void init_creature(struct creature *c) {
    c->speed = random_number();
    c->size = random_number();
}

int main() {
    struct creature creatures[10];

    for (int i = 0; i < (sizeof(creatures)/sizeof(struct creature)); i++) {
        struct creature c = creatures[i];
        init_creature(&c);
    }
}

struct это, вероятно, то, что вы ищете здесь.

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

Таким образом, представляя ваши существа в C, вы можете иметь такую ​​структуру:

struct creature {
  int x_pos;
  int y_pos;
  int speed;
};

Чтобы объявить существо "объектом" и установить некоторые свойства, вы должны сделать это так:

   void main() {
      struct creature mycreature;
      mycreature.x_pos = 1;
      mycreature.y_pos = 2;      
   }

struct creature mycreature синтаксис немного громоздкий, поэтому люди часто typedef структурирует, чтобы им не нужно было говорить struct creature mycreature и может вместо этого просто сказать creature mycreature:

typedef struct _creature {
  int x_pos;
  int y_pos;
  int speed;
} creature;

Структура может содержать другие структуры, поэтому вы также можете создать point структурируйте и используйте это вместо переменных местоположения:

typedef struct _point {
  int x;
  int y;
} point;

typedef struct _creature {
  point location;
  int speed;
} creature;

void main() {
    creature mycreature;
    mycreature.location.x = 1;
    mycreature.location.y = 2;      
}

И теперь, надеюсь, все станет выглядеть немного более знакомым...

Другие вопросы по тегам