Is (*exptr)->cnt the same as exptr->cnt or (*exptr).cnt?
No.
(*pointer)->name
says “Get the thing that pointer
points to. Get the structure that it points to and get the name
member from it.” For this to work, pointer
must be a pointer to a pointer to a structure. For example, it could have been declared as struct foo **pointer
.
pointer->name
says “Get the structure that pointer
points to and get the name
member from it.” For this to work, pointer
must be a pointer to a structure. It could have been declared as struct foo *pointer
.
(*pointer).name
says “Get the structure that pointer
points to. Get the name
member from it.” It also must be a pointer
to a structure.
(The only difference between the last two is that the second uses one operator in source code. The operations actually performed are the same.)
In C, the a->b
operator is a shorthand for (*a).b
.
struct foo {
int b;
};
// the . operator is used when the struct object is NOT a pointer
struct foo a;
a.b = 42;
// the -> operator is used when the struct object IS a pointer
struct foo *a = malloc(sizeof *a);
a->b = 42;
// the same thing as the above example, but using the dot operator
(*a).b = 42;
The last example is dereferencing the a
pointer (getting the object it points to), then using the dot operator to access the element b
inside of it. Now let's translate your question.
// first one
(*a)->b;
// would be the same as:
(*(*a)).b;
// that is:
(**a).b;
// which would be used in
struct foo **a ... ;
(**a).b; // get the first element of the array, access field b
// second example
a->b;
// is the same as
(*a).b;
// which is your third example