In his book Patterns in C, Adam Petersen describes using a pointer to a struct, which is declared in a header file, to create a first-class abstract data-type:/* Customer.h *//* A pointer to an incomplete type (hides the implementation details). */typedef struct Customer* CustomerPtr;/* Create a Customer and return a handle to it. */CustomerPtr createCustomer(const char* name, const Address* address);/* Destroy the given Customer. All handles to it will be invalidated. */void destroyCustomer(CustomerPtr customer);The struct and the two functions are defined in Customer.c:#include Customer.h#include <stdlib.h>struct Customer{    const char* name;    Address address;    size_t noOfOrders;    Order orders[42];};CustomerPtr createCustomer(const char* name, const Address* address){    CustomerPtr customer = malloc(sizeof * customer);    if(customer)    {        /* Initialize each field in the customer... */    }    return customer;}void destroyCustomer(CustomerPtr customer){    /* Perform clean-up of the customer internals, if necessary. */    free(customer);}The way I would organize my code is a bit different.  The header file would declare the struct itself, not a pointer to it.  Here is the way I was taught of coding something similar:/* Customer.h */struct Customer;extern struct Customer* newCustomer(const char* name);and declarations:/* Customer.c */struct Customer {    char name[CUSTNAMELENGTH +1];};struct Customer* newCustomer(const char* name) {    struct Customer* newCustomer;    newCustomer = malloc(sizeof(struct Customer));    /* initialize customer instance */    return newCustomer;}What is the practical difference between the two styles?  Is there a potential problem with my way that I don't see?  It seems to successfully encapsulate the object, and provide an interface similar to Petersen's design. When should I use his design rather than what I have been doing?
What is the proper way to implement an abstract data type in C?
design patterns;c;data types;headers
These are not that different. Both .h files effectively declare struct Customer as a forward declaration.  The first one also defines a pointer type, which the second doesn't.  Some prefer the typedef as they don't like to write struct and *; I would probably agree.  The extern declaration is good, but not necessary, I believe.  Otherwise, the naming createCustomer vs. newCustomer is fairly arbitrary to me.One could be more critical about the two styles except that the neither is very complete; the second example even less so.FYI, Both of these have potential errors.  The first malloc's only a single pointer instead of a struct (it  references struct * customer instead of struct Customer, so it won't compile either).  It also allocates a fixed size of 42 for the orders, which doesn't make a lot of sense to me; it would probably be better to make it an expandable data structure (although, the astute reader may note that in C/C++ a structure that ends with an array is potentially expandable -- still if one were doing that they'd use something like zero as the array size.)The second assumes a fixed customer name length, which if sufficiently large is wasteful when not needed, and, presumably can still be exceeded.  It would probably be better to allocate strings to size, which would avoid both the space waste and the overflow issue.