tags:

views:

111

answers:

6

Ok this may be a silly question for many of you. Let me preface this with a list in order of the languages I've learned over the past 10 years. [by the way, I understand that some of these are scripting languages]

  • vb 6.0
  • html
  • asp
  • php
  • css
  • javascript
  • managed c++
  • c#
  • c++
  • C
  • ASM

Yeah I know I started at the complete opposite end, but hopefully the list keeps me from getting criticized to much with this one heh.

QUESTION: Are there classes in plain old C...I know there are structures... Also I would like to know if you can declare functions in C structures/classes(if they exist). I think the answer to both is no, but It's hard to find information on plain C on the internet as most things are for C++. Also, I am interested in knowing any tips, tricks, or warning for working with C. Much thanks in advance.

BTW: I'm interested in C for the purpose of portability and speed.

A: 

C has no classes, and structs in C cannot have functions within them.

Ned Batchelder
what about `struct {int (*f) (void); }`?
wallyk
That is a pointer to a function, not a function.
Ned Batchelder
pointer to functions can be declared inside a struct just to provide some polymorphism in C, there has been a lot of discussion about this earlier at SO.
Prasoon Saurav
@Ned Batchelder - It is, but that's what I was looking for. An answer and possible alternatives.
kelton52
+3  A: 

C doesn't have classes. That was one reason for the creation of C++, besides function overloading, operator overloading, and templates.

Of course, code acting class-like was sometimes written long before the existence of C++:

typedef struct class1 class1;

struct class1 {
    int (*constructor) (class1 *this);
    int (*destructor) (class1 *this);
    ...
};
wallyk
That's brilliant.
kelton52
+4  A: 

Classes in C are most often simulated by structs combined with function pointers. Non-virtual functions can be passed alongside a pointer to the struct, like so:

int obj_compare_funct(Obj *a, Obj *b);
int result = compare_two_objects(obj1, obj2, obj_compare_func);

But the real fun starts when you embed the pointers in the struct; this means objects of the same overall "class" can have different "methods". The biggest syntactic downside is that the function pointed to does not automatically know for which object it is being called. So the object needs to be passed as well, which makes for a bit more typing than is normally desirable. For instance:

/***** In the animal.h header file. *****/
typedef struct Animal {
    char *name;
    void (* speak)(Animal *this);   /* The speak "method" */
} Animal;

/* Constructors for various animal types.  Implementation detail: set the animal's speak method to the appropriate one for that animal type. */
extern Animal *make_feline(char *name);
extern Animal *make_rodent(char *name);

/***** Somewhere in zoo.c, which #includes animal.h. *****/
Animal *cat = make_feline("Tom");
Animal *mouse = make_rodent("Jerry");

cat->speak(cat);  /* Print "Tom says meow!" */
mouse->speak(mouse);  /* Print "Jerry says squeak!" */

This example is a bit looser than the inheritance model provided by languages such as Java -- an Animal instance can have any behaviour at all, rather than one of a specific set of behaviours depending on its subclass. To make things a bit stricter, the methods are usually combined into a struct called a vtable (virtual function table). One vtable is pre-made for each subtype, and the appropriate one pointed to from the instance.

Note that none of this directly helps you have different fields for each subtype -- that's trickier (especially syntactically) and can be done either by the trick of casting an object to its first member, e.g.:

/* Can be treated as an Animal if you cast its pointer. */
typedef struct Cat { Animal super; int num_fleas; } Cat;

Or using opaque pointers, e.g.

typedef struct Animal { char *name; void *species_specific_data; } Animal;

Where the extra fields would be hidden away behind that void * pointer, and accessible through the methods particular to that species.

Edmund
Why do you use extern?
kelton52
I just wanted to say, "these functions exist, but I don't want to show their implementations right here". I know it's not quite right, and if it's a distraction I should probably remove it...
Edmund
No no, I've seen extern used before, I was just unsure of its meaning.
kelton52
Ah. Basically, if you say "extern f;" in a C file, you're telling the compiler that f will be provided by some other file. The compiler needs to know a few bare minimum things, such as f's type. For a function, that includes the return type and argument types.
Edmund
2 more questions. You use 'this' above, but the actual 'this' pointer doesn't exist in C, correct? So you are simulating it I'm assuming. Second, you specify 'Animal super', and super turns blue like it's a keyword, is it? And what is it used for. Thanks.
kelton52
You're right about "this". I could have picked a different name, and usually I do! I probably should have, because it's been coloured as a keyword, when it's just another variable here. The same problem with "super". But these are the most convenient names to use because they have the same *meaning* as in C++, if not precisely the same syntax.
Edmund
+1  A: 

There are many differences between C and C++ structs, and yes C doesn't have classes.

For example consider the following code:

struct demo
{
    int a;//public by default

    void set()// valid in C++, invalid in C
    {
        //do something with a
    }
};

Other differences between C and C++ structs are:

->Constructors and destructors for object initialization and destruction purpose.

->Support of operator overloading, templates,exception handling mechanism etc in C++ structs.

Properties shared between structs in C and POD-structs in C++:

1)Data members are allocated so that later members have higher addresses within an object, except where separated by an access-specifier.

2)Two POD-struct types are layout-compatible if they have the same number of nonstatic data members, and corresponding nonstatic data members (in order) have layout-compatible types. A POD-struct may contain unnamed padding.

3)A pointer to a POD-struct object, suitably converted using a reinterpret cast, points to its initial member and vice versa, implying that there is no padding at the beginning of a POD-struct.

4)A POD-struct may be used with the offsetof macro.

Source -wiki

Prasoon Saurav
What does POD stand for?
kelton52
Plain Old Data.
Prasoon Saurav
A: 

Remember that C was created in 1972, well before the ideas of object-oriented programming was common. At the time, object-oriented programming was limited to very few languages, like Simula 67.

So, no, C does not have classes.

Chip Uni
A: 

Great book on C, from the creator of the language.

Swaraj