1

I recently transferred into a different school & cs program. The language used is C as compared to java which was taught at my previous school. One of my main issues which may be the result of not writing enough C code is that I'm having trouble finding a standard for making Abstract Data Types.

From what I've seen, there are tons of ways these are implemented and the lack of a visible standard is making me worried I missed something while self learning C. I've seen implementations that hide the init variable from the user such as

#define createVector(vec) Vector vec; void init_vector(&vec)

and another version which is what I would be more used to in which a handle is used to hold the returned pointer to struct from the createVector() function. The issue is I can't find any detailed description on handles online or in my course 2 book. The course 2 book only shows the interface and methods but not how they are grouped together in a way that hides the implementation from the user. I wanted to know if there was a "correct" way/standard for ADTs? The book in question is Robert Sedgewick "Algorithms in C - Third Edition".

Michael
  • 67
  • 8
  • 2
    You can make a struct with either function pointers, or name the functions appropriately to make it clear that they are tied to the struct. E.g. a linked list with function pointers could look like that: https://github.com/Xatenev/c-algorithms/blob/master/src/data-structures/linked-list/LinkedList.h – Xatenev Aug 08 '19 at 15:41
  • 3
    There is no de jure (as in "ISO" or "ECMA") standard for the process that I'm aware of. There are multiple de facto standards — all those different variations you've found. The macro you show would go a long way down my list of suggested 'good ideas'. – Jonathan Leffler Aug 08 '19 at 16:45

3 Answers3

1

Abstract Data Types

Split your sources. The header (.h files) contains the abstract declarations like the datatypes (structs, functions, enums, constants, etc) The actual implementation is done in the .c files. When using such a (lets call it) module you only include the header in your source. The implementiation you use is decided at linking time. You may decide to use different .c files for implementation or a static library (or even a dynamic library). If you want to hide the data you use opaque structures.

Why is this standard? Ever heard of the FILE type? This is the opaque type used for IO in c's standardlibrary. You only include the header stdio.h and leave the implementation to the compiler. The header on the other hand or at least the symbols that it defines are well documented (and part of the c standard).

Abstract Classes

Java has the concept of an abstract class. Well, it also has the concept of a class in general. C does not. This is more a personal opinion but don't waste time on emulating language features that the language does not offer. For none abstract methods use functions which take a pointer to a (probably opaque) struct containing all the data needed as first parameter, like fprintf(FILE*,const char*,...). For abstract methods you will need function pointers. Use these function pointers (or maybe a struct of function pointers) like a strategy. You may define a method for registering such a strategyand delegate the normal functions to them. Take for example the atexit function, which globally (you may call it a singleton) adds a exiting-strategy.

The XY Problem

I'm having trouble finding a standard for making Abstract Data Types

Read about this and apply it to your question. Instead of trying to force your solution to work rethink if the attempted solution is applicable to the problem. Try to get comfy with the techniques described above. This may need a bit of practice but then you can model your solution in a more c-styled way.

Community
  • 1
  • 1
Burdui
  • 1,242
  • 2
  • 10
  • 24
  • After finishing the course this question is based on, you were correct about opaque data structures. In general we used a void* to hold the actual object and a struct that contained said void* and the functions it can use. We then made a macro so that the function calls for each object referenced the object/void* in the struct – Michael Jan 13 '20 at 13:18
0

I just wanted to post this as I figured out the answer that would be more specific to my case however I understand that this probably doesn't apply to everyone. The thing I was looking for was the idea of "First Class ADTs" which use a handle to contain a pointer to the actual object that was created from a .c implementation file that would be hidden from the user.

Michael
  • 67
  • 8
0

For ADT using C, this approach is the standard as far as I know. You will have a header (.h) file and one or more implementation (.c) files. The header file might look something like:

typedef struct * Doodad;

Doodad * doodadInit(int);

void doodadDestroy(Doodad *);

int doodadGetData(Doodad *);

void doodadSetData(int);

For your implementation file(s) you might have:

typedef struct iDoodad {
   int data;
} Doodad;

Doodad * doodadInit(int data) {
   ...
}

...
Fracdroid
  • 1,135
  • 10
  • 15