Does using C mean defining basic data structure every time?

Started by
8 comments, last by mrbastard 12 years ago
I am a CS student, I have long been writing C&C++ mixing codes. I mean I use C++ compiler such as VS2008, but actually I am not good at OOP, so I just write C-like codes using C++. Many times I define a class and soon I will feel the design is bad, making the problem more complex. Sometimes I define a lot interfaces today and change all my minds tomorrow and re-write them all.

So finally I don't want to struggle any more. I know C grammar pretty well, so I think I'd better just use pure C, forgetting the C++ features. These days I am trying to write a pure C program, maybe thousonds lines of codes. A problem I met is that, I have been used to use STL data structure such as vector for a long time, but C doesn't have STL. I tried to write some general data structure like linked list, using function pointers to apply general operations. But soon I found it's not so easy to be general.

So I want to know how does professional C programmer write their daily codes? For example, when a linked list is used to organize some data, will you directly operate the pointer to next node in the application's algorithm, or will make an abstraction to hide the details of linked list?

Thanks for your time.
Advertisement

Many times I define a class and soon I will feel the design is bad, making the problem more complex. Sometimes I define a lot interfaces today and change all my minds tomorrow and re-write them all.


That problem won't really go away if you switch to pure C, though, except that you obviously won't be writing any classes. Instead you'll write a set of functions operating on a certain type of data and then change your mind the next day and rewrite them all.


So I want to know how does professional C programmer write their daily codes? For example, when a linked list is used to organize some data, will you directly operate the pointer to next node in the application's algorithm, or will make an abstraction to hide the details of linked list?


There are probably various third-party libraries available that provide somewhat generic data structures such as lists and so on. It's just that in C, "generic" usually means mucking around with void-Pointers and constantly casting to the type of data you're using the structure with.
You can still write a hybrid between c and c++. You don't have to use deep inheritance graphs and interfaces for everything. When you say you tend to rewrite your code often that seems to me like a lack of design on your side.
It is perfectly ok to use C++ without any OOP-functionality, I often do this for really small programs and experiments. So I would recommend to sticking with C++ as a language instead of ressorting to C.

But on your question; As there are probably libraries to use to get stuff like linked lists etc. but as far as I remember pure C does not support templates which will be a pain.

[quote name='smile55' timestamp='1333006533' post='4926250']
Many times I define a class and soon I will feel the design is bad, making the problem more complex. Sometimes I define a lot interfaces today and change all my minds tomorrow and re-write them all.


That problem won't really go away if you switch to pure C, though, except that you obviously won't be writing any classes. Instead you'll write a set of functions operating on a certain type of data and then change your mind the next day and rewrite them all.


So I want to know how does professional C programmer write their daily codes? For example, when a linked list is used to organize some data, will you directly operate the pointer to next node in the application's algorithm, or will make an abstraction to hide the details of linked list?


There are probably various third-party libraries available that provide somewhat generic data structures such as lists and so on. It's just that in C, "generic" usually means mucking around with void-Pointers and constantly casting to the type of data you're using the structure with.
[/quote]

Really thanks for your replies.

Actually I am doing exact things you descripted: writing function to operate some data, as a class in C++, but with functions. From some books I read that abstraction is important because it decreases the complexity. But I always feel it's hard to do it. Sometimes I think programming without abstraction, just use plain data, may be more efficient, as I can waste less time designing interfaces and abandon thems, and may feel less frustrated.

Maybe I read wrong book. Books I read always tell the concepts, list a lot of its advantages but doesn't teach how to really do it. Even SICP, I read the two chapers and half the third chapter and did the most exercises in these chapters, doesn't help a lot. I feel the programs in these books are always too ideal or just toy programs. But practical programs are more dirty. Do you have some recommended books? Or should I read some sources code of open source projects?

And actually my point is not whether there are some third-party library for C. I'm asking whether professional C programmers write some general data structure once and use them frequently after (or just use some third-party libraries), or just combine these data structures into the applications' algorithm?
It takes time (read years) to become a good at anything. I wouldn't give up C++ even if it is a hard to master, especially if the option is going back to plain C. There are just too many good features in C++ which make your life so much easier (after you learn the proper way of using them). For example I feel that I couldn't live without the std::vectors/lists etc. They alone have solved so many problems I have struggled earlier. Proper usage of them doesn't even hurt the performance.

You'll need to take a step at a time and code in the fashion that you feel comfortable even if it means mix of C++ and C. Recoding, refactoring is healthy when learning things. Few days I go I realized that certain part of my engine code falls in to a certain abstractable pattern and I could implement the functionality it in a much much easier way. Something that I wish I had understood some months earlier.

Otherwise, have you tried other languages?

[quote name='Red Ant' timestamp='1333007625' post='4926255']
[quote name='smile55' timestamp='1333006533' post='4926250']
Many times I define a class and soon I will feel the design is bad, making the problem more complex. Sometimes I define a lot interfaces today and change all my minds tomorrow and re-write them all.


That problem won't really go away if you switch to pure C, though, except that you obviously won't be writing any classes. Instead you'll write a set of functions operating on a certain type of data and then change your mind the next day and rewrite them all.


So I want to know how does professional C programmer write their daily codes? For example, when a linked list is used to organize some data, will you directly operate the pointer to next node in the application's algorithm, or will make an abstraction to hide the details of linked list?


There are probably various third-party libraries available that provide somewhat generic data structures such as lists and so on. It's just that in C, "generic" usually means mucking around with void-Pointers and constantly casting to the type of data you're using the structure with.
[/quote]

Really thanks for your replies.

Actually I am doing exact things you descripted: writing function to operate some data, as a class in C++, but with functions. From some books I read that abstraction is important because it decreases the complexity. But I always feel it's hard to do it. Sometimes I think programming without abstraction, just use plain data, may be more efficient, as I can waste less time designing interfaces and abandon thems, and may feel less frustrated.

Maybe I read wrong book. Books I read always tell the concepts, list a lot of its advantages but doesn't teach how to really do it. Even SICP, I read the two chapers and half the third chapter and did the most exercises in these chapters, doesn't help a lot. I feel the programs in these books are always too ideal or just toy programs. But practical programs are more dirty. Do you have some recommended books? Or should I read some sources code of open source projects?

And actually my point is not whether there are some third-party library for C. I'm asking whether professional C programmers write some general data structure once and use them frequently after (or just use some third-party libraries), or just combine these data structures into the applications' algorithm?
[/quote]

Library development is common in programming. It is the process of building on abstractions. It sounds like you're asking if C programmers use libraries to which the answer is simply "yes".

Now, I'm more confused about why you want to use C instead of C++. You have already said you're using a C++ compiler and IDE. It sounds to me like you are running against issues with learning the language because you perceive it to be harder than to continue on with what you know. It doesn't sound like you're making this choice for any actual technical reason.

I can assure you that while in the short term it may be easier to hack out a few hundred lines of code (rather than learn the standard library) it won't pay off long term. Implementing your own container classes might feel more comfortable, but it is also much more likely that you're introducing memory leaks and probably lacks the efficiency of the STL (it's hard to beat a couple decades of testing and design even for specific applications of problems by seasoned programmers, and impossible to when you're first learning the language).

It sounds like you're in need of a good book, or a complete change in language (maybe try python or something else). There is very little reason to restrict yourself to C in this day and age, maybe only for some specific embedded systems does it make sense. The power of templates and the benefit of classes and the standard library is huge (not to mention boost and other C++ libraries).

Finally, and probably most fundamentally, C is not a great language for container classes primarily because of the lack of template support. You can simulate object oriented programming in C by passing around structs to functions which modify state, but it's harder to simulate std::vector or std::list type functionality primarily because the underlying methods do not exist in the language. That is, in fact, the primary reason C++ exists. It offers a lot of extra stuff that C simply does not, much of that is directly a result of why you are asking this question now and are unsure about library development.

There are quite a few high quality C libraries for specific purposes, but it is a lot harder to write good generic code for C. Generic C code often involves a lot of void* casting or macros.

So now that I've given you the advice you actually need, I'll tackle the advice you asked for.

Here's a decent rundown of a few options for C libraries: http://programmers.s...t-library-for-c

And more specifically here is a generic macro based container library: http://sglib.sourceforge.net/

Ultimately the question you've got to ask yourself is: if I download a non-standard library and invest time in reading and understanding how to use it then what am I REALLY gaining over simply biting the bullet and learning a little more about the C++ standard library?
_______________________"You're using a screwdriver to nail some glue to a ming vase. " -ToohrVyk
rewriting things always gives you a chance to code things better, because you have a better global understanding of the problem you are trying to solve.
While you are a student this is exactly the exercise to do to get better at programming... once you're out in the real world, you'll have deadlines, and the time to dedicate to rewrite and refactor will become precious and rare... so enjoy doing it while you can.

Stefano Casillo
TWITTER: [twitter]KunosStefano[/twitter]
AssettoCorsa - netKar PRO - Kunos Simulazioni


A problem I met is that, I have been used to use STL data structure such as vector for a long time, but C doesn't have STL. I tried to write some general data structure like linked list, using function pointers to apply general operations. But soon I found it's not so easy to be general. So I want to know how does professional C programmer write their daily codes? For example, when a linked list is used to organize some data, will you directly operate the pointer to next node in the application's algorithm, or will make an abstraction to hide the details of linked list?
I'm in the opposite situation where I'm writing C-style code and data-structures in C++, because simple C-inspired structures have a lot of benefits over C++-style structures like the STL collections...[source lang=cpp]template<class T> struct Offset
{
const T* Ptr() const { return (T*)(((u8*)&offset) + offset); }
T* Ptr() { return (T*)(((u8*)&offset) + offset); }
const T* operator->() const { return Ptr(); }
T* operator->() { return Ptr(); }
const T& operator *() const { return *Ptr(); }
T& operator *() { return *Ptr(); }
uint DataSize() const { return sizeof(T); }
private:
s32 offset;
};

template<class T> struct Array
{
const T* Ptr() const { return (T*)(((u8*)&offset) + offset); }
T* Ptr() { return (T*)(((u8*)&offset) + offset); }
const T& operator *() const { return *Ptr(); }
T& operator *() { return *Ptr(); }
const T& operator[](uint i) const { return Ptr(); }
T& operator[](uint i) { return Ptr(); }
uint DataSize(uint count) const { return sizeof(T) * count; }
private:
s32 offset;
};

template<class T> struct Address
{
const T* Ptr(const void* base) const { return (T*)(((u8*)base) + offset); }
T* Ptr(const void* base) { return (T*)(((u8*)base) + offset); }
uint DataSize() const { return sizeof(T); }
private:
u32 offset;
};

template<class T> struct List
{
u32 Count() const { return count; }
const T* Begin() const { return (T*)(&count + 1); }
T* Begin() { return (T*)(&count + 1); }
const T* End () const { return Begin()+count; }
T* End () { return Begin()+count; }
const T& operator[](uint i) const { eiASSERT(i < count); return Begin(); }
T& operator[](uint i) { eiASSERT(i < count); return Begin(); }
uint DataSize() const { return sizeof(T) * count; }
private:
u32 count;
};

struct String { u8 length; u8 chars; };

struct StringOffset
{
bool operator==( const StringOffset& other )
{
const String& a = *this->Ptr();
const String& b = *other.Ptr();
return unlikely(&a==&b) || ( unlikely((offset&~0xFFFFU)==(other.offset&~0xFFFFU))
&& likely(a.length==b.length)
&& likely(0==memcmp(&a.chars, &b.chars, a.length)) );
}
const String* Ptr() const { return (String*)(((u8*)&offset) + (offset&0xFFFFU)); }
String* Ptr() { return (String*)(((u8*)&offset) + (offset&0xFFFFU)); }
const String* operator->() const { return Ptr(); }
String* operator->() { return Ptr(); }
const String& operator *() const { return *Ptr(); }
String& operator *() { return *Ptr(); }
private:
s32 offset;
};[/source]

writing C-style code and data-structures in C++, because simple C-inspired structures have a lot of benefits over C++-style structures like the STL collections


Sounds familiar - I wrote a striding iterator template many years ago - uses templates and a smidgen of inheritance from c++, but really just encapsulates c-style pointer arithmentic. Meant I could still use STL algorithms on plain c blobs of data, or someone's misguided vector clone.

To the OP: have you spent much time with the 'static duck typing' method of polymorphism used with templates? You may find it suits your tastes better than the more usual OO style with virtuals and inheritance.
[size="1"]

This topic is closed to new replies.

Advertisement