我正在理解 gethostbyname()
函数。
当时我找到了下面的示例程序。
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *host, **names, **addrs;
struct hostent *hostinfo;
if(argc == 1)
{
char myname[256];
gethostname(myname, 255);
host = myname;
}
else
host = argv[1];
hostinfo = gethostbyname(host);
if(!hostinfo)
{
fprintf(stderr, "cannot get info for host: %s\n", host);
exit(1);
}
printf("results for host %s:\n", host);
printf("Name: %s\n", hostinfo -> h_name);
printf("Aliases:");
names = hostinfo -> h_aliases;
while(*names)
{
printf("%s", *names);
names++;
}
printf("\n");
if(hostinfo -> h_addrtype != AF_INET)
{
fprintf(stderr, "not an IP host!\n");
exit(1);
}
addrs = hostinfo -> h_addr_list;
while(*addrs)
{
printf(" %s", inet_ntoa(*(struct in_addr *)*addrs));
addrs++;
}
printf("\n");
exit(0);
}
现在我在我的系统上运行它。 它工作正常。有两件事让我感到困惑:
- 在 inet_ntoa 函数中,我们将其类型化为
inet_ntoa(*(struct in_addr *)*addrs)
。 但是如果我们像inet_ntoa((struct in_addr) addrs)
这样的类型,那么它是行不通的。 我无法理解这背后的原因。还请解释一下这里进行了什么样的类型转换。 当我理解这个程序的时候。我也无法理解以下 while 循环。
同时(*地址) { printf("%s", inet_ntoa(*(struct in_addr *)*addrs)); 地址++;
请解释一下。
假设有一个
char**test
指向字符串“india”。当我们做过类似test++
的事情时。它根据字符串大小递增。在这种情况下,它将递增 6(5 + 1(null char.))。为什么会这样?
最佳答案
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.
为此,您必须知道 in_addr
类型的定义是什么。来自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.
这里的结构有一个 union ,我们感兴趣的是 chars
。因为 addrs
是类型 char**
当我们执行 *addrs
时我们得到 char*
这是衰减类型char
数组。在类型转换中,我们手动将 char*
转换为 struct in_addr*
。但是inet_ntoa按值而非引用获取 in_addr
对象。因此,我们向转换类型添加另一个 * 以将其从 in_addr*
更改为 in_addr
。如果没有这种情况,执行 **addrs
将给出 char
而不是 in_addr
。
II. while(*addrs) { printf(" %s", inet_ntoa(*(struct in_addr *)*addrs)); addrs++; }
为了理解这个循环,您已经看到从哪里加载addrs
:struct hostent::h_aliases
,MSDN 再次将其记录为
A NULL-terminated array of alternate names.
addrs
指向一个带有终止 NULL 元素的字符序列(字符串)数组。例如char *addrs[] = { "Delhi", "London", "New York", NULL };
我们知道 addrs
是非空的,但是 *addrs
将只有三次非空,当检查为 while(*addrs)
时,第四个元素将为 NULL。
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?
错了! char **test = "india";
是非法的。然而,就像我上面解释的那样,它将指向一个这样的字符串数组。当您执行 addrs++
时,真正发生的不是基于字符串长度递增,而是递增一个元素。当您执行 *addrs
时,它将指向“Delhi”,然后 addrs++
和 *addrs
现在将指向“London”,依此类推.
我建议您阅读 C FAQ有关数组到指针衰减、指针算法等的详细信息。
关于c - 无法理解在 inet_ntoa 函数中完成的类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20137363/