在 C 中无需对象进行管理 - 为什么我可以在 C 函数中的任何位置声明变量?
每个人。我实际上有两个问题,有些相关。
问题#1:为什么 gcc 让我在操作语句之后声明变量?我认为C89标准不允许这样做。 (GCC 版本:4.4.3)当我在编译行显式使用 --std=c89
时,甚至会发生这种情况。我知道大多数编译器实现了非标准的东西,即当标准没有指定时,C 编译器允许 //
注释。我只想学习标准,这样如果我需要使用仅仅标准,我就不会遇到这样的事情。
问题#2:在 C 中没有对象时如何应对?我将编程作为一种爱好,而且我还没有使用过没有对象的语言(又名 OO 概念?)——我已经了解一些 C++,并且我想学习如何单独使用 C。据说,一种方法是创建一个 POD 结构并创建类似于 StructName_constructor()
、StructName_doSomething()
等的函数,并将结构实例传递给每个函数 - 是这样“正确”的方式,还是我完全离开了?
编辑:由于一些轻微的混乱,我正在更清楚地定义我的第二个问题:我不是在问如何在C中使用对象?
我在问如何在没有对象的情况下进行管理在 C 中?
,又名如何在没有对象的情况下完成任务,通常使用对象?
提前,非常感谢。我从来没有使用过没有 OOP 的语言! :)
编辑:根据要求,这里是变量声明问题的示例:
/* includes, or whatever */
int main(int argc, char *argv[]) {
int myInt = 5;
printf("myInt is %d\n", myInt);
int test = 4; /* This does not result in a compile error */
printf("Test is %d\n", test);
return 0;
}
everyone. I actually have two questions, somewhat related.
Question #1: Why is gcc letting me declare variables after action statements? I thought the C89 standard did not allow this. (GCC Version: 4.4.3) It even happens when I explicitly use --std=c89
on the compile line. I know that most compilers implement things that are non-standard, i.e. C compilers allowing //
comments, when the standard does not specify that. I'd like to learn just the standard, so that if I ever need to use just the standard, I don't snag on things like this.
Question #2: How do you cope without objects in C? I program as a hobby, and I have not yet used a language that does not have Objects (a.k.a. OO concepts?) -- I already know some C++, and I'd like to learn how to use C on it's own. Supposedly, one way is to make a POD struct and make functions similar to StructName_constructor()
, StructName_doSomething()
, etc. and pass the struct instance to each function - is this the 'proper' way, or am I totally off?
EDIT: Due to some minor confusion, I am defining what my second question is more clearly: I am not asking How do I use Objects in C?
I am asking How do you manage without objects in C?
, a.k.a. how do you accomplish things without objects, where you'd normally use objects?
In advance, thanks a lot. I've never used a language without OOP! :)
EDIT: As per request, here is an example of the variable declaration issue:
/* includes, or whatever */
int main(int argc, char *argv[]) {
int myInt = 5;
printf("myInt is %d\n", myInt);
int test = 4; /* This does not result in a compile error */
printf("Test is %d\n", test);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您坚持这样做,是的,您可以传递一个指向结构的指针作为
this
的模仿 - 但这仍然不是一个好主意。当您需要操作数据结构时,传递结构(指向)通常是有意义的。然而,我不建议非常努力地将函数分组在一起,并让它们都将指向结构的指针作为它们的第一个参数,只是因为这就是其他语言实现事物的方式。
如果您碰巧有许多函数都在特定结构上运行/使用特定结构,并且它们都接收指向该结构的指针作为其第一个参数确实有意义,那很好 - 但不必觉得有必要强制它只是因为 C++ 碰巧就是这样做的。
编辑:至于如何在没有对象的情况下进行管理:嗯,至少在我编写 C 时,我倾向于更频繁地对单个字符进行操作。无论如何,在 C++ 中,我通常会得到几行相对较长的代码;在 C 语言中,我倾向于使用很多短行。
代码和数据之间有更多的分离,但在某种程度上它们仍然是耦合的——例如二叉树仍然需要代码来插入节点、删除节点、遍历树等。同样,这些操作需要了解结构的布局以及指针的名称等。
就我个人而言,我更倾向于在 C 代码中使用通用命名约定,因此(举几个例子)二叉树中指向子树的指针始终仅命名为
left
和right.如果我使用链表(很少见),则指向下一个节点的指针始终命名为
next
(如果它是双向链接的,则另一个为prev
)。这对编写代码有很大帮助,而无需花费大量时间查找结构定义来找出我这次使用的名称。If you insist on doing it anyway, yes, you can pass a pointer to a struct as an imitation of
this
-- but it's still not a good idea.It does often make sense to pass (pointers to) structs around when you need to operate on a data structure. I would not, however, advise working very hard at grouping functions together and having them all take a pointer to a struct as their first parameter, just because that's how other languages happen to implement things.
If you happen to have a number of functions that all operate on/with a particular struct, and it really makes sense for them to all receive a pointer to that struct as their first parameter, that's great -- but don't feel obliged to force it just because C++ happens to do things that way.
Edit: As far as how you manage without objects: well, at least when I'm writing C, I tend to operate on individual characters more often. For what it's worth, in C++ I typically end up with a few relatively long lines of code; in C, I tend toward a lot of short lines instead.
There is more separation between the code and data, but to some extent they're still coupled anyway -- a binary tree (for example) still needs code to insert nodes, delete nodes, walk the tree, etc. Likewise, the code for those operations needs to know about the layout of the structure, and the names given to the pointers and such.
Personally, I tend more toward using a common naming convention in my C code, so (for a few examples) the pointers to subtrees in a binary tree are always just named
left
andright
. If I use a linked list (rare) the pointer to the next node is always namednext
(and if it's doubly-linked, the other isprev
). This helps a lot with being able to write code without having to spend a lot of time looking up a structure definition to figure out what name I used for something this time.@问题#1:我不知道为什么没有错误,但你是对的,变量必须在块的开头声明。好处是你可以在任何你喜欢的地方声明块:)。例如:
@问题#2:实际上在没有继承的情况下进行 C 编程有时非常烦人。但在某种程度上,OOP 是有可能的。例如,查看 GTK 源代码,您会发现一些示例。
你是对的,像你所展示的那样的函数很常见,但构造函数通常分为分配函数和初始化函数。 EG:
在某些库中,我什至看到了某种多态性,其中函数指针存储在结构中(当然,必须在初始化函数中设置)。这会产生类似 C++ 的 API:
@Question #1: I don't know why there is no error, but you are right, variables have to be declared at the beginning of a block. Good thing is you can declare blocks anywhere you like :). E.g:
@Question #2: actually programming C without inheritance is sometimes quite annoying. but there are possibilities to have OOP to some degree. For example, look at the GTK source code and you will find some examples.
You are right, functions like the ones you have shown are common, but the constructor is commonly devided into an allocation function and an initialization function. E.G:
In some libraries, I have even seen some sort of polymorphism, where function pointers are stored within the struct (which have to be set in the initializing function, of course). This results in a C++ like API:
关于C中的OOP,你看过SO上的一些主题吗?例如,你能用 C 语言编写面向对象的代码吗? 。
我无法具体说明示例,但我认为他们在 Linux 内核编程中也强制执行类似 OO 的规则。
Regarding OOP in C, have you looked at some of the topics on SO? For instance, Can you write object oriented code in C?.
I can't put my finger on an example, but I think they enforce an OO like discipline in Linux kernel programming as well.
就学习 C 的工作原理而言,与 C++ 中的 OO 相比,您可能会发现使用其他没有 OO 派生语言的短期课程更容易,例如 Modula-2(我最喜欢的语言之一)甚至 BASIC(如果您仍然可以找到真正的 BASIC 实现 - 上次我编写 BASIC 代码时是使用 DOS 5.0 附带的 QBASIC,后来编译为完整的 Quick BASIC)。
在 Modula-2 或 Pascal 中完成任务所使用的方法(除了强类型,它可以防止某些类型的错误,但使执行某些操作变得更加复杂)正是在非 OO C 中使用的方法,并且在具有不同语法的语言可能(可能会,IMO)使您更容易学习这些概念,而无需您的“编程反射”启动并尝试用几乎熟悉的语言进行面向对象操作。
In terms of learning how C works, as opposed to OO in C++, you might find it easier to take a short course in some other language that doesn't have an OO derivative -- say, Modula-2 (one of my favorites) or even BASIC (if you can still find a real BASIC implementation -- last time I wrote BASIC code it was with the QBASIC that came with DOS 5.0, later compiled in full Quick BASIC).
The methods you use to get things done in Modula-2 or Pascal (barring the strong typing, which protects against certain types of errors but makes it more complicated to do certain things) are exactly those used in non-OO C, and working in a language with different syntax might (probably will, IMO) make it easier to learn the concepts without your "programming reflexes" kicking in and trying to do OO operations in a nearly-familiar language.