Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 强制转换指针后程序未编译_C_Pointers - Fatal编程技术网

C 强制转换指针后程序未编译

C 强制转换指针后程序未编译,c,pointers,C,Pointers,这是我的密码: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> int main (void) { struct addrinfo hints; mems

这是我的密码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main (void) {

  struct addrinfo hints; 
  memset (&hints, 0, sizeof hints);

  hints.ai_family = AF_UNSPEC; 
  hints.ai_socktype = SOCK_DGRAM;  
  hints.ai_flags = AI_CANONNAME;   

  struct addrinfo *res;

  getaddrinfo ("example.com", "http", &hints, &res);
  printf ("Host: %s\n", "example.com");

  void *ptr;

  while (res != NULL) {

    printf("AI Family for current addrinfo: %i\n", res->ai_family);

    switch (res->ai_family) {
      case AF_INET:
        struct sockaddr_in *sockAddrIn = (struct sockaddr_in *) res->ai_addr;
        printf("Port number: %u\n", ntohs(sockAddrIn->sin_port));
        printf("IP address is: %u\n", ntohs(sockAddrIn->sin_addr.s_addr));
        break;
    }
    res = res->ai_next;
  }

  return 0;
}
我试图做的是将
void
指针投射到*中的
struct sockaddr\u。编译错误是:

ex3.c:33:48:错误:成员引用基类型“void”不是 结构或结合

printf("IP address is: %u\n", ntohs(ptr->sin_addr.s_addr));
我做错了什么?为什么指针
ptr
未浇铸

为什么指针ptr没有浇铸

显然,这里的
cast
ing本身没有问题。问题在于代码后面使用了
void
指针
ptr

在您的例子中,
ptr
是指向
void
类型的指针。与
struct
指针相比,它没有任何类型信息。将带有
cast
ing的指针放入
void*
变量不会更改
void*
变量本身的类型。它仍然是一个不完整的类型,不能用作操作数到成员(de)引用运算符

换句话说,
void
类型不能有成员,因此成员引用是完全错误的

我看不出做
ptr
a
void*
有什么用。也许,您想将
ptr
定义为

 struct sockaddr_in * ptr = NULL;
回避这个问题


也就是说,
%u
不是与
uint16\u t
类型一起使用的格式说明符(返回类型为
ntohs()
)。您可能希望使用
PRIu16
作为格式说明符。

类型
ptr
void*
,您需要在延迟之前将强制转换添加到适当的类型

回想一下:C不允许取消对不完整类型的引用。根据C规范,
void
属于不完整类型

一个简单的修复方法是在*
中将ptr的类型更改为
struct sockaddr\u

您也可以在
printf
行本身中添加强制转换,但这会给代码添加不必要的混乱。

此行:

ptr = (struct sockaddr_in *) res->ai_addr;
不做你认为它做的事;它不会自动将*
中的
ptr
类型设置为
struct sockaddr\u,因此您仍在尝试取消引用
void
指针。你需要做的是

printf("Port number: %u\n", ntohs(((struct sockaddr_in *) res->ai_addr)->sin_port));

将ptr的声明更改为

void * ptr;

ptr=(struct sockaddr_in*)res->ai_addr

这是你的错误。ptr是一个空指针,您将为其分配一个结构指针。 因此,您必须首先创建一个结构指针,并将强制转换的结果分配给该指针

struct sockaddr_in *ptr;
ptr = (struct sockaddr_in *) res->ai_addr;

这里是演员阵容:ptr=(struct sockaddr_in*)res->ai_addr;是的,但是
ptr
的类型仍然是
void
。那么这个代码做什么呢ptr=(struct sockaddr_in*)res->ai_addr?@KorayTugay将
res->ai_addr
显式转换为(as)
struct sockaddr_in*
,然后隐式转换为
void*
,并分配给ptr。请注意,程序中变量的值可能会更改,但类型不会更改。下面是强制转换:ptr=(struct sockaddr_in*)res->ai_addr@KorayTugay演员阵容不会改变
ptr
的类型,是吗?:-)@KorayTugay不多-将
res->ai_addr
的值赋给
ptr
,但
ptr
的类型保持不变。@KorayTugay告诉我们如何解释
res->ai_addr
作为指向
中的
结构sockaddr\u的指针,但
ptr
保持
void*
。但在本文中:一个答案是:void*会自动安全地升级为任何其他指针类型。这不是我要问的。你确定吗?看起来你是基于代码片段。是的,我确定。如果你愿意的话,看看斯祖尔西奥的回答。他说的和我说的一样:-/不,他没有。无论如何,谢谢。如果可以的话,再问一个问题。为什么是这个printf(“IP地址是:%u\n”,ntohs(sockAddrIn->sin_addr.s_addr));还在打印23992?我希望得到类似于120.32.3.2..@KorayTugay的两个问题-首先,
ntohs
代表
network to host short
-short意味着两个字节,就像端口一样。您需要
ntohl
。第二,IPv4地址实际上是32位整数。要将其转换为十进制点表示法(我们已经习惯了),可以使用
inet\u ntoa
,或者更好的方法是使用
inet\u ntop
(尽管前者的语法更简单)。请注意,如果使用这些函数,则不需要将
sin\u addr
转换为主机字节顺序,因为它们会为您处理该顺序。
sockaddr_in* ptr;
struct sockaddr_in *ptr;
ptr = (struct sockaddr_in *) res->ai_addr;