gpt4 book ai didi

转换新元素以将它们附加到单链表中

转载 作者:行者123 更新时间:2023-11-30 17:50:07 25 4
gpt4 key购买 nike

我有一个关于在 C 中的单链表中附加和转换新元素的问题。在决定提问之前我做了一些研究,并找到了 similar question 的一些答案。 ,这在一定程度上解决了我的疑问,但我仍然没有完全理解为什么需要进行一些转换来取悦编译器。

我在 Ubuntu 12.04 LTS 中使用 gcc:

$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.

所以我实现了以下代码:

 1  #include <stdio.h>
2 #include <stdlib.h>
3
4 typedef struct {
5 struct node* next;
6 int data;
7 } node;
8
9 node* appendElement(node* head, int data);
10 node* removeElement(node* head, int data);
11
12 int main(int argc, char** args){
13 //main code
14 return 0;
15 }
16
17 node* appendElement(node* head, int data){
18 node* newElement;
19 if(head == NULL){
20 if((newElement = malloc(sizeof(node))) != NULL){
21 newElement->data = data;
22 newElement->next = NULL;
23 return newElement;
24 }
25 else{
26 fprintf(stderr, "Error");
27 return NULL;
28 }
29 }
30 else{
31 node* n = head;
32 while(n->next != NULL){
33 n = (node*)n->next;
34 }
35 if((newElement = malloc(sizeof(node))) != NULL){
36 newElement->data = data;
37 newElement->next = NULL;
38 n->next = (void*)newElement;
39 return head;
40 }
41 else{
42 fprintf(stderr, "Error");
43 return NULL;
44 }
45 }
46 }
47
48 node* removeElement(node* head, int data){
49 node* aux;
50 if(head == NULL){
51 printf("Empty list, nothing to remove.\n");
52 return NULL;
53 }
54 else if(head->data == data){
55 aux = (node*)head->next;
56 free(head);
57 return aux;
58 }
59 else{
60 node* n = head;
61 while(n->next != NULL){
62 aux = (node*)n->next;
63 if(aux->data == data){
64 n->next = aux->next;
65 free(aux);
66 return head;
67 }
68 n = (node*)n->next;
69 }
70 printf("Can't find %d in list.\n", data);
71 return head;
72 }
73 }

从我读到的答案来看,可以改变:

4  typedef struct {
5 struct node* next;
6 int data;
7 } node;

进入:

4  typedef struct _node {
5 struct _node* next;
6 int data;
7 } node;

为了避免以下几行中的显式转换:

33  n = (node*)n->next;
38 n->next = (void*)newElement;
62 aux = (node*)n->next;
68 n = (node*)n->next;

正如人们所期望的那样,它有效。我知道编译器“不喜欢”使用未定义的结构。 (而且 malloc 的参数可以是 newElement。)

我的问题是:如果不想更改结构声明怎么办?为什么需要这些转换才能让编译器满意?我相信即使没有这些 Actor ,该程序仍然有效。

特别是,我必须在第 38 行实现的对 void* 的转换根本无法让我信服。我知道 void* 是一个通用指针,因此每个指针都可以毫无问题地向下转换,这就是我使用它的原因。

也许我对结构体声明和typedef的理解并没有我想象的那么好。感谢您抽出时间。

编辑:更正了一些代码以更加清晰。

最佳答案

你的结构定义错误:

typedef  struct  {
struct node* next;
int data;
} node;

第二行将 next 声明为指向名为 node 的未知结构的指针。这是未知的,因为您尚未声明。将 struct node* next 更改为 struct junk* next ,编译将产生相同的结果。编译器可以继续超越这一点,因为它不需要知道“节点”有多大,它只需要知道这是一个指针。

通常将此类事情定义为:

struct node {
struct node* next;
int data;
};
typedef struct node node;

这是有效的,因为当编译器进行您引用的分配时,它知道什么是结构节点。在您的版本中,您从未定义什么是结构节点。请注意,我在 typedef 中使用了与结构中相同的名称,即“node”。这是可以的,因为 typedef 和结构是不同的命名空间(因此可以重叠)。

关于转换新元素以将它们附加到单链表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17460841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com