1

I'm confused by pointers to structs in C and part of my problem is that the examples I find are seemingly wrong.

In this example code I found here, I still get the dreaded error:

warning: assignment from incompatible pointer type

#include <stdio.h>

struct Book
{
    char name[10];
    int price;
}

int main()
{
    struct Book a;      //Single structure variable
    struct Book* ptr;   //Pointer of Structure type
    ptr = &a;

    struct Book b[10];  //Array of structure variables
    struct Book* p;     //Pointer of Structure type
    p = &b;  

    return 0;
}

Does anybody have a working example for me to learn from?

Ronan Boiteau
  • 9,608
  • 6
  • 34
  • 56
alternum5
  • 75
  • 8
  • 2
    Any medium-sized open-source project will have dozens of the "working examples". – Eugene Sh. Mar 26 '18 at 17:37
  • 3
    When you do `struct Book b[10]`, `b` is itself a pointer, to the first element of the array. Therefore, when you do `p = &b` you're not getting a `Book*`, you're getting a `Book**`, a pointer TO the pointer variable `b`. `p = b` or `p = &b[0]` would be valid `Book*` values – rdowell Mar 26 '18 at 17:43
  • 1
    Don't try to get information about C from random internet sites. You are likely to get burnt. Get a book with a good reputation. – n. m. could be an AI Mar 26 '18 at 17:47
  • @rdowell Please do **not** perpetuate the myth that "an array is a pointer". **`b` is an array**. In most contexts, use of the name of that array will degenerate into a pointer to the first element of the array, but that does not make `b` a pointer. Please follow @n.m.'s recommendation; I suggest K&R2. – mlp Mar 26 '18 at 18:15
  • The referenced example (and your posted code) have several errors, so do not compile! the first glaring error is that a struct definition end with a semicolon. The posted code and the referenced example are both missing that semicolon. – user3629249 Mar 27 '18 at 14:46
  • regarding: `p = &b;` When an array name is referenced, it degrades to the address of the first byte of the array. So this is asking for the address of the address. IT should be: `p = b;`. However, a clear/better example would be: `p = &b[0];` – user3629249 Mar 27 '18 at 14:57

2 Answers2

2

Change:

p = &b;

Into:

p = b;

This is because b is [already] an array. So, b by itself refers to the whole array and the result points to the first element (i.e. &b[0]). What you had generates a Book ** instead of a Book * [1].

So, this would also work:

p = &b[0];

UPDATE:

[1] My bad. This actually generates struct Book (*)[10] which is a pointer to an array of fixed size (e.g. 10) of Book structs, which is [slightly] different than a simple Book pointer. This adds the array length as part of the type, so pointer/type matching is more exacting/complex.

A struct Book (*)[10] does not match [typewise] to struct Book * and would not match to a different length fixed array size pointer (e.g. struct Book (*)[20]) even though the base type (struct Book) is the same.

However, once defined, dereferencing/indexing of the pointer would be similar.

Usage of this herein was inadvertent. This is a bit of an advanced feature/technique that can be avoided for now. I've rarely [if ever] encountered it in practice.

For more information, see: C pointers : pointing to an array of fixed size

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
0

b is already pointer to struct, so simple p = b; should do the job.

I recommend reading Chapter 5 Pointers and Arrays of K&R to fully understand relationship between pointers and arrays.