当我决定自学编程时,我从Java开始。尽管我熟悉编写简单的过程软件(主要是用PHP),但我最近意识到,对于更复杂的操作,我依赖对象。
我的第一款Java游戏通过实例化对象在随机位置以随机速度生成对手。我对在C中实现这个过程的概念感到困惑(我几乎没有工作知识),但我只能想到为每个对手中的变量创建不同的数组,并使用数组索引作为伪对象引用"变量"。
int size[50]; // opponent size
for (i = 0; i < 100; i++) {
size[i] = random_number();
}
有一个简单的解决方案,我的面向对象的思想忽略了吗?或者,某些问题是否真的适合面向对象的概念,以至于您不得不编造虚假的对象(或者至少使用类似的模型)?我一直在C代码中看到结构体,我知道它们在概念上类似于类,但我只知道这些。所以我想知道这样的东西在完全非面向对象的思维模式下是否可能。实例化没有真正的替代品,不是吗?这只是内存的分配,所以在我看来,某些C程序别无选择,只能使用我所认为的某种形式的对象来编写。
请告诉我我忽略了什么,否则我就不能尊重那些谴责面向对象范式的C纯粹主义者。(我绝不是OO狂人;不过,我的大脑已经非常习惯了这个想法,很难从不同的角度看待事物,而不是从你习惯的角度来看。
谢谢!
作为一个从OO程序员起步的人,我也花了一点时间来习惯过程编程。对我来说,最重要的事情是习惯使用指针,并记住函数不是由对象管理的,而是作用于你给它们的"对象"。无论如何,我认为像这样的东西可能是你正在寻找的,它可以帮助你对你正在尝试做的事情有一个程序性的印象。
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);
}
}
如果我们忽略所有高级的面向对象编程概念,如通过类型参数继承或多态性,一切都归结为同样的事情。
在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
可能是您在这里寻找的。
struct
可以包含任意数量的命名变量(如类的属性),但不能包含方法(理论上你可以通过函数指针将方法放入其中,但这不会真正按照你想要的方式工作)。
用C语言表示你的生物,你可能有这样一个结构体:
struct creature {
int x_pos;
int y_pos;
int speed;
};
要声明一个生物"object"并设置一些属性,你可以这样做:
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;
}
现在事情开始看起来更熟悉了…