Как бы я "породил" или создал бы несколько существ процедурно?
Когда я решил научиться программировать, я начал с 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;
}
И теперь, надеюсь, все станет выглядеть немного более знакомым...