Question: How do I declare, versus define a struct, such as for data shared between multiple files. I understand the idea when defining primitives. So, for example, I might have:

```
extern int myvalue;  /* in shared header file */

```

and

```
int myvalue = 5;   /* in data.c file */

```

But, how do I do the same thing for structs. For example, if I have the following type:

```
   typedef struct {
       size_t size;
       char * strings[];
   } STRLIST;

```

If I then use the statement:

```
STRLIST list;

```

This is both a declaration and definition. So, how do apply the same principle of using an extern?

Answer: 
To declare an *instance of* a struct (or a pointer to one):

```
extern STRLIST* ptrList;
extern STRLIST list;

```

To define it:

```
STRLIST* ptrList;
STRLIST list;

```

To declare a *struct type*:

```
typedef struct STRLIST;

```

To define it:

```
typedef struct {
    size_t size;
    char * strings[];
} STRLIST;

```

Note that you can use a pointer to a struct with only a declaration, but you must have a definition to use the struct directly.
Just a small clarification to dbush's answer:

From the latest C standard (Feb 2020): 

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2494.pdf>

> 
> 6.7.2.1 Structure and union specifiers (p1)
> 
> 
> Syntax
> 
> 
> 1 struct-or-union-specifier:
> 
> 
> struct-or-union attribute-specifier-sequenceopt identifieropt {
>  member-declaration-list }
> 
> 
> 

In conclusion, the part:

```
struct STRLIST{
    size_t size;
    char * strings[];
};

```

Is your struct's declaration.

Adding the typedef, defines the *type* STRLIST:

```
typedef struct {
    size_t size;
    char * strings[];
} STRLIST;

```

And this is your definition:

```
STRLIST list;

```

Rule of thumb: a definition provides memory to the instance. a declaration doesn't.