struct Book {
    int i;
} variable, *ptr;
while accessing struct memebers we use variable.i or ptr->i my question is what is the difference between/use of variable and *ptr
struct Book {
    int i;
} variable, *ptr;
while accessing struct memebers we use variable.i or ptr->i my question is what is the difference between/use of variable and *ptr
 
    
    Imagine a dog.
Now imagine a dog leash.
Now imagine the dog, clipped to the leash.
The leash represents a pointer to the dog. If you create a pointer (leash) and don't also have a structure to point to (dog), then you can't go to the park and play frisbee.
If you have a structure, but don't have a pointer, you can still do lots of things.
Using a pointer requires having a structure to point to. You can either declare a structure, and then point to it using the & operator, or you can call a function like malloc or calloc which will return dynamically allocated memory that you can use as the structure:
void demo() {
    struct Book b1;
    struct Book b2;
    typedef struct Book * Bookptr;
    Bookptr p;
    // Assign pointer to existing object using address operator:
    p = &b1;
    p->i = 10;
    p = &b2;
    p->i = 12;
    printf("Book 1 has i: %d, while Book 2 has i: %d\n", b1.i, b2.i);
    // Use dynamically allocated memory
    p = calloc(1, sizeof(struct Book));
    p->i = 3;
    printf("Dynamic book has i: %d\n", p->i);
    free(p);
}
 
    
    variable will have memory associated with it and therefore can be directly accessed when created.  Because the memory is given at compile time, the . means the compiler can directly lookup the values in the structure without having to do any sort of in-direct jumping 
ptr will only be a pointer to memory and cannot be used until pointed at something that has memory (or given memory via a dynamic memory allocation.)  The -> means the compiler must read the memory first and then jump to the location.
