C 何时对结构使用指针与直接成员

C 何时对结构使用指针与直接成员,c,sockets,pointers,struct,C,Sockets,Pointers,Struct,所以我在C中找到了关于套接字的精彩教程。到目前为止,这一切都是有意义的,但我很好奇,我看到了同时使用指针和不使用指针的结构。我很困惑什么时候应该或者不应该为结构使用指针 我在教程中找到了以下示例: #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #define MAX_LE

所以我在C中找到了关于套接字的精彩教程。到目前为止,这一切都是有意义的,但我很好奇,我看到了同时使用指针和不使用指针的结构。我很困惑什么时候应该或者不应该为结构使用指针

我在教程中找到了以下示例:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>

#define MAX_LENGTH 2000

int main(int argc, char *argv[]) {

    int socket_desc;
    struct sockaddr_in server;
    char *message, server_reply[MAX_LENGTH];

    socket_desc = socket(AF_INET, SOCK_STREAM, 0);

    if (socket_desc == -1) {
        puts("Could not create socket :(");
    }

    server.sin_addr.s_addr = inet_addr("173.194.121.2");
    server.sin_family = AF_INET;
    server.sin_port = htons(80);

    if (connect(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
        puts("Connection error.");
        return 1;
    }
    puts("Connected!\n");

    close(socket_desc);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#定义最大长度2000
int main(int argc,char*argv[]){
内部插座描述;
服务器中的结构sockaddr_;
字符*消息,服务器回复[最大长度];
socket\u desc=socket(AF\u INET,SOCK\u STREAM,0);
如果(套接字描述==-1){
puts(“无法创建套接字:(”);
}
server.sin_addr.s_addr=inet_addr(“173.194.121.2”);
server.sinu family=AF\u INET;
server.sin_port=htons(80);
if(connect(socket_desc,(struct sockaddr*)&server,sizeof(server))<0{
puts(“连接错误”);
返回1;
}
放置(“已连接!\n”);
关闭(插座描述);
返回0;
}
因此,我决定将服务器变量转换为指针,看看发生了什么。下面是我的想法:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>

#define MAX_LENGTH 2000

int main(int argc, char *argv[]) {

    int socket_desc;
    struct sockaddr_in *server;
    char *message, server_reply[MAX_LENGTH];

    socket_desc = socket(AF_INET, SOCK_STREAM, 0);

    if (socket_desc == -1) {
        puts("Could not create socket :(");
    }

    server->sin_addr.s_addr = inet_addr("173.194.121.2");
    server->sin_family = AF_INET;
    server->sin_port = htons(80);

    if (connect(socket_desc, (struct sockaddr *)server, sizeof(*server)) < 0) {
        puts("Connection error.");
        return 1;
    }
    puts("Connected!\n");

    close(socket_desc);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#定义最大长度2000
int main(int argc,char*argv[]){
内部插座描述;
*服务器中的结构sockaddr_;
字符*消息,服务器回复[最大长度];
socket\u desc=socket(AF\u INET,SOCK\u STREAM,0);
如果(套接字描述==-1){
puts(“无法创建套接字:(”);
}
服务器->sin_addr.s_addr=inet_addr(“173.194.121.2”);
服务器->sin_family=AF_INET;
服务器->单端口=htons(80);
if(连接(socket_desc,(struct sockaddr*)服务器,sizeof(*server))<0){
puts(“连接错误”);
返回1;
}
放置(“已连接!\n”);
关闭(插座描述);
返回0;
}
这也编译得很好,但在运行时给了我一个
分段错误:11


所以我的问题是,为什么这段代码不起作用,我如何知道何时需要指向结构或普通结构的指针。谢谢!

在第一个版本中,您声明了一个完整的结构,这意味着结构的内存放在堆栈上

在第二个版本中,您声明了一个指向该结构的指针,但没有为其分配内存,因此当您尝试寻址该结构不存在的成员时,您可能会出错

如果将第二个更改为为为结构分配内存:

struct sockaddr_in *server = malloc(sizeof(struct sockaddr_in));
然后记得
释放(服务器);
退出之前,您将正确处理内存

要回答问题的第二部分,如果需要将数据(在本例中为连接信息)存储在其他数据结构中以跟踪数据,或者出于某种原因需要将数据传递给其他例程,则可能只需要指向结构的指针


但是,对于后一种情况,通常使用
&
运算符获取堆栈上的结构用作指向例程的指针的地址,就像在第一个例程中的
connect()
调用中一样,它使用以下参数执行此操作:
(struct sockaddr*)&服务器

在第一个版本中,声明了一个完整的结构,这意味着该结构的内存放在堆栈上

在第二个版本中,您声明了一个指向该结构的指针,但没有为其分配内存,因此当您尝试寻址该结构不存在的成员时,您可能会出错

如果将第二个更改为为为结构分配内存:

struct sockaddr_in *server = malloc(sizeof(struct sockaddr_in));
然后记得
释放(服务器);
退出之前,您将正确处理内存

要回答问题的第二部分,如果需要将数据(在本例中为连接信息)存储在其他数据结构中以跟踪数据,或者出于某种原因需要将数据传递给其他例程,则可能只需要指向结构的指针


但是,对于后一种情况,通常使用
&
运算符获取堆栈上的结构用作指向例程的指针的地址,就像在第一个例程中的
connect()
调用中一样,它使用以下参数执行此操作:
(struct sockaddr*)&服务器

服务器是一个指针。它指向什么?您没有告诉。服务器可以指向结构sock\u addr\u in,但它没有


这就像一辆车在路上开得很好,但您正试图在路标上驾驶它。

服务器是一个指针。它指向什么?您没有告诉。服务器可以指向一个struct sock\u addr\u in,但它没有


这就像一辆汽车在路上开得很好,但您正试图在路标上驾驶它。

如果您传递指针的API打算取消引用该指针,并代表您在其中存储一个值,那么您需要传递一个有效的内存位置,以便存储操作将成功


如果您向其传递指针的API只打算将指针传递回您(如通过回调函数),则指针值可以是在获取值时对您有意义的任何值。

如果要向其传递指针的API打算取消引用该指针,并代表您在其中存储值,则需要向其传递有效的内存位置,以便存储操作成功


如果您向其传递指针的API只打算将指针传递回您(如通过回调函数),则指针值可以是在您获取值时对您有意义的任何值。

在这种情况下没有理由使用指针。事实上,在您学会如何处理它们之前,使用指针将导致相当多的崩溃。问题是,除非您必须使用指针,否则不要使用指针,在这种情况下,您真的不必使用指针。Hav你学过指针吗?你使用指针是完全错误的。@ikh不是很久了。我已经有一段时间没有学过C了,所以我正在重新学习我知道的一点。我使用指针的方式有什么问题吗