我理解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\u ntoa函数中,我们有类似于inet_ntoa(*(struct in_addr *)*addrs)的case类型。
但是如果我们像inet_ntoa((struct in_addr) addrs)那样做类型的情况,那么它就不起作用了。
我不明白这背后的原因请解释一下这里是什么类型的铸造。
当我理解这个程序的时候我也不能理解下面的while循环。
while(*地址)
{
printf(“%s”,inet_ntoa(*(struct in_addr*)*地址));
地址++;
}
请给我解释一下。
假设有一个char**test指向字符串“india”当我们做过类似于test++的事情时它根据字符串大小递增在这种情况下,它将增加6(5+1(空字符)为什么?

最佳答案

I.在inet_ntoa函数中,我们有类似inet_ntoa(*(struct In_addr*)*addrs的case但是如果我们像inet_ntoa((struct in_addr)addrs)那样使用类型case,那么它就不起作用了我不明白这背后的原因请解释一下这里是什么类型的铸造。
为此,您必须知道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.

在这里,这个结构有一个联合,我们对它感兴趣的是chars由于addrschar**类型,当我们做*addrs时,我们得到char*这是char数组的衰减类型在类型转换中,我们手动将char*转换为struct in_addr*但是inet_ntoa按值接受一个in_addr对象,而不是引用因此,我们向casted类型添加另一个*以将其从in_addr*更改为in_addr如果不做**addrs的话,会得到一个char而不是一个in_addr
二while(*addr s){printf(“%s”,inet_ntoa(*(struct in_addr*)*addrs));addrs++;}
为了理解这个循环,您已经看到了从哪里加载addrs的位置:struct hostent::h_aliases它再次将MSDN文档作为以空结尾的备用名称数组。
addrs指向具有终止空元素的字符序列(字符串)数组例如,char *addrs[] = { "Delhi", "London", "New York", NULL };我们知道addrs是非空的,但是*addrs只会是非空的三次,当检查为while(*addrs)时,第四个元素将是空的。
III.假设有一个单字符**测试指向字符串“india”我们什么时候做过类似test++它根据字符串大小递增在这种情况下,它将增加6(5+1(空字符)为什么?
错了char **test = "india";是非法的但是,正如我在上面所解释的,它将指向这样的字符串数组当您执行addrs++时,实际发生的并不是基于字符串长度递增,而是仅仅由元素递增当你这样做时,它将指向“德里”,然后*addrsaddrs++现在将指向“伦敦”等等。
我建议您阅读C FAQ以了解有关数组到指针衰减、指针算法等的详细信息。

09-25 16:56