I. In the inet_ntoa function, we have type case it like inet_ntoa(*(struct in_addr *)*addrs). But If we do the type case like inet_ntoa((struct in_addr) addrs).Then It is not working. I am not able to understand the reason behind this. Please also explain me that what kind of type casting is done here.
For this you've to know what is the definition of the type in_addr
is. From MSDN
typedef struct in_addr {
union {
struct {
u_char s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct {
u_short s_w1,s_w2;
} S_un_w;
u_long S_addr;
} S_un;
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
Members:
S_un
S_un_b: An IPv4 address formatted as four u_chars.
S_un_w: An IPv4 address formatted as two u_shorts.
S_addr: An IPv4 address formatted as a u_long.
Here the structure has a union out of which our interest is in chars
. Since addrs
is of type char**
when we do *addrs
we get char*
which is the decayed type of char
array. In the type cast we manually convert char*
to struct in_addr*
. But inet_ntoa takes an in_addr
object by value and not reference. Thus we add another * to the casted type to change it from in_addr*
to in_addr
. Without the case doing **addrs
would give a char
and not a in_addr
.
II. while(*addrs) { printf(" %s", inet_ntoa(*(struct in_addr *)*addrs)); addrs++; }
To understand this loop you've see where you load addrs
from: struct hostent::h_aliases
which again MSDN documents as
A NULL-terminated array of alternate names.
addrs
is pointing to an array of character sequences (strings) with a terminating NULL element. For e.g. char *addrs[] = { "Delhi", "London", "New York", NULL };
We know that addrs
is non-null, but *addrs
will be non-null only thrice, the fourth element would be NULL when checked as while(*addrs)
.
III. Suppose there is a one char**test which is pointing to string "india". When Ever we done something like test++. It is incremented according to the string size. In this case It will be incremented by 6(5 + 1(null char.)). Why so?
Wrong! char **test = "india";
is illegal. However, like I've explained above, it'll be pointing to an array of such strings. When you do a addrs++
, what really happens is not incremented based on the string length but just increment by an element. When you do *addrs
it'll point to "Delhi", then addrs++
and *addrs
will now point to "London" and so on.
I would recommend that you read C FAQ for details on array to pointer decay, pointer arithmetic, etc.