C programming. How do I hide the implementation of a struct in .c if I need to refer to its instance in a header (.h) file

So, I'm curious about how to hide the implementation of a struct in a .c file if we need to refer to its instance in a header file. For example, I have the following structure in a header file:

struct List
{
    NodePtr front;    
};

      

I want to declare NodePtr in a .c file to hide its implementation. In .c:

struct Node
{
    void *value;
    struct Node *next;
};

typedef struct Node *NodePtr;

      

But of course the .h file doesn't know what NodePtr is ....

How can I do it right?

+3


source to share


2 answers


Something like this should work fine. Note that the definition struct Node

never leaves List.c

.

list.h

#pragma once
#include <stdbool.h>

struct List {
    struct Node *front;
};

void list_init(struct List **list);
void list_free(struct List *list);
void list_insert(struct List *list, void *value);
bool list_contains(struct List *list, void *value);

      

list.c



#include <stdbool.h>
#include <stdlib.h>
#include "list.h"

struct Node {
    void *value;
    struct Node *next;
};

void list_init(struct List **list) {
    *list = malloc(sizeof(**list));
}

void list_free(struct List *list) {
    struct Node *node = list->front;
    while (node != NULL) {
        struct Node *next = node->next;
        free(node);
        node = next;
    }
    free(list);
}

void list_insert(struct List *list, void *value) {
    struct Node *node = malloc(sizeof(*node));
    node->value = value;
    node->next = list->front;
    list->front = node;
}

bool list_contains(struct List *list, void *value) {
    struct Node *node;
    for (node = list->front; node != NULL; node = node->next)
        if (node->value == value)
            return true;
    return false;
}

      

main.c

#include <stdio.h>
#include "list.h"

int main() {
    struct List *l;
    list_init(&l);

    int *value_1 = malloc(sizeof(int));
    int *value_2 = malloc(sizeof(int));
    int *value_3 = malloc(sizeof(int));

    list_insert(l, value_1);
    list_insert(l, value_2);
    list_insert(l, value_3);

    printf("Does the list contain value_1: %d\n", list_contains(l, value_1));
    printf("Does the list contain null:    %d\n", list_contains(l, NULL));

    list_free(l);
    return 0;
}

      

It is very possible that I have some errors in this code. If you see them, feel free to fix them.

+4


source


You have the right to say:

typedef struct Node *NodePtr;
struct List
{
    NodePtr front;    
};

      



this typedef struct Node *NodePtr;

is an announcement ahead. You can use it as long as you use pointers for types. Pointers do not need to know the structure of the type (classes). And the compiler is happy.

+1


source







All Articles