codeblocks 输出与在线编译器不同
codeblocks output differs from online compilers
简而言之,我应该有“ 1 2 3 4 5 6 7 8 9 10 ”。
当在 CodeBlocks 而不是 0 中执行时,我得到随机数。但是当使用在线编译器编译时,我得到了预期的输出。哪个输出靠谱?在线还是 CodeblockIDE 的?
如果需要的话还有链表练习的代码:创建,输入数据元素,指定点删除,最后输出结果。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node *next;
} SLNode;
void ListInitiate(SLNode **head) /* Initialization */
{
/* If there is memory space, apply the head node space and make the head pointer point to the head node */
if((*head = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);
(*head)->next = NULL; /* set the last of the list as Null */
}
int ListLength(SLNode *head) /* Get the size of the linked list */
{
SLNode *p = head;
int size = 1;
while(p->next != NULL) /*count with loop*/
{
p = p->next;
size ++;
}
return size;
}
int ListInsert(SLNode *head, int i, DataType x)
/* Insert a node that contains the data element x before the node ai (0 ≤ i ≤ size) of the linked list with header */
{
SLNode *p, *q;
int j;
p = head; /* p points to the head*/
j = -1; /* the initial value of j is -1*/
while(p->next != NULL && j < i - 1)
/* Finally let pointer p point to data element ai-1 node */
{
p = p->next;
j++;
}
if(j != i - 1)
{
printf("Insert position parameter wrong!");
return 0;
}
/* q points to the new node*/
if((q = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);
q->data = x;
/* There is an error blow*/
q->next = p->next;
p->next = q;
return 1;
}
int ListDelete(SLNode *head, int i, DataType *x)
/* delete the node ai of the list with a header*/
/* put the data element of the node in x. If success, return 1; if fail, return 0*/
{
SLNode *p, *s;
int j;
p = head;
j = -1;
while(p->next != NULL && p->next->next!= NULL && j < i - 1)
/*Finally let pointer p point to data element ai-1 node */
{
p = p->next;
j++;
}
if(j!= i - 1)
{
printf("Insert position parameter wrong!");
return 0;
}
s = p->next; /*s points to ai*/
*x = s->data; /*Assign the data field value of the node pointed by pointer s to x */
p->next = s->next; /* delete ai*/
free(s); /* free the memory space of s */
return 1;
}
int ListGet(SLNode *head, int i, DataType *x)
/*The function of taking the data element ai is similar to deleting ai function, but do not delete the data element ai node*/
{
SLNode *p;
int j;
p = head;
j = 0;
while(p->next != NULL && j < i)
{
p = p->next;
j++;
}
if(j != i)
{
printf("The position of the parameter is wrong!");
return 0;
}
*x = p->data;
return 1;
}
void Destroy(SLNode **head)
{
SLNode *p, *p1;
p = *head;
while(p != NULL)
{
p1 = p;
p = p->next;
free(p1);
}
*head = NULL;
}
void main(void)
{
SLNode *head;
int i , x;
ListInitiate(&head);
for(i = 0; i < 10; i++)
{
if(ListInsert(head, i, i+1) == 0) /*insert ten data elements*/
{
printf("Error!! \n");
return;
}
}
if(ListDelete(head, 4, &x) == 0) /* delete data element 5*/
{
printf("error! \n");
return;
}
for(i = 0; i < ListLength(head); i++)
{
if(ListGet(head, i, &x) == 0) /* take out the element*/
{
printf("Error! \n");
return;
}
else printf("%d ", x); /* show data elements*/
}
Destroy(&head);
}
问题出在您的代码逻辑上。好的输出是 Code::Blocks 一个。
问题出在 insertNode
函数中。它的行为如下:它找到第 i-1 个节点并在它之后创建一个新节点。如果 i = 0
,第 0 个元素是在你的第一个循环的第一次迭代中找到的,之后不会有错误,因为 j = i - 1 = -1
。永远不要在你的代码中编辑头部的数据。
此外,每次调用 insertNode
函数时,您都会要求新节点的值为其位置 + 1.
所以你会得到这个:
---------- ----- -----
| random | ---> | 1 | ---> | 2 | ---> etc.
---------- ----- -----
head 0th 1st
之后,在 listGet
函数中,您对列表的制作方式产生了误解。例如,当调用 listGet(head, 0, &x)
时,条件 p->next != NULL && j < i
总是在第一次迭代时满足,这意味着返回的节点不是第 0 个,而是头。你应该改为写 :
j = -1; // 0 become -1
while(p->next != NULL && j < i)
{
p = p->next;
j++;
}
此外,您必须更改主循环中的边界。确实,listLength
returns 列表中元素的数量(这里是 10),但是索引不是从 1 bt 从 0 开始,这意味着你不能停在 10(因为有没有第 10 个节点)但在 9。因此你必须写:
for(i = 0; i < ListLength(head) - 1; i++)
{
if(ListGet(head, i, &x) == 0) /* take out the element*/
{
printf("Error! \n");
return 1;
}
else printf("%d ", x); /* show data elements*/
}
还有一点与此问题无关,但无论如何您都必须更正:您的 destroy 函数。
void Destroy(SLNode **head)
{
SLNode *p, *p1;
p = *head;
while(p != NULL)
{
p1 = p;
p = p->next;
/* make NULL assignment here */
p1->next = NULL;
free(p1);
}
/* head has been already freed in the above loop
* do not try to manipulate it */
// *head = NULL;
}
简而言之,我应该有“ 1 2 3 4 5 6 7 8 9 10 ”。 当在 CodeBlocks 而不是 0 中执行时,我得到随机数。但是当使用在线编译器编译时,我得到了预期的输出。哪个输出靠谱?在线还是 CodeblockIDE 的? 如果需要的话还有链表练习的代码:创建,输入数据元素,指定点删除,最后输出结果。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node *next;
} SLNode;
void ListInitiate(SLNode **head) /* Initialization */
{
/* If there is memory space, apply the head node space and make the head pointer point to the head node */
if((*head = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);
(*head)->next = NULL; /* set the last of the list as Null */
}
int ListLength(SLNode *head) /* Get the size of the linked list */
{
SLNode *p = head;
int size = 1;
while(p->next != NULL) /*count with loop*/
{
p = p->next;
size ++;
}
return size;
}
int ListInsert(SLNode *head, int i, DataType x)
/* Insert a node that contains the data element x before the node ai (0 ≤ i ≤ size) of the linked list with header */
{
SLNode *p, *q;
int j;
p = head; /* p points to the head*/
j = -1; /* the initial value of j is -1*/
while(p->next != NULL && j < i - 1)
/* Finally let pointer p point to data element ai-1 node */
{
p = p->next;
j++;
}
if(j != i - 1)
{
printf("Insert position parameter wrong!");
return 0;
}
/* q points to the new node*/
if((q = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);
q->data = x;
/* There is an error blow*/
q->next = p->next;
p->next = q;
return 1;
}
int ListDelete(SLNode *head, int i, DataType *x)
/* delete the node ai of the list with a header*/
/* put the data element of the node in x. If success, return 1; if fail, return 0*/
{
SLNode *p, *s;
int j;
p = head;
j = -1;
while(p->next != NULL && p->next->next!= NULL && j < i - 1)
/*Finally let pointer p point to data element ai-1 node */
{
p = p->next;
j++;
}
if(j!= i - 1)
{
printf("Insert position parameter wrong!");
return 0;
}
s = p->next; /*s points to ai*/
*x = s->data; /*Assign the data field value of the node pointed by pointer s to x */
p->next = s->next; /* delete ai*/
free(s); /* free the memory space of s */
return 1;
}
int ListGet(SLNode *head, int i, DataType *x)
/*The function of taking the data element ai is similar to deleting ai function, but do not delete the data element ai node*/
{
SLNode *p;
int j;
p = head;
j = 0;
while(p->next != NULL && j < i)
{
p = p->next;
j++;
}
if(j != i)
{
printf("The position of the parameter is wrong!");
return 0;
}
*x = p->data;
return 1;
}
void Destroy(SLNode **head)
{
SLNode *p, *p1;
p = *head;
while(p != NULL)
{
p1 = p;
p = p->next;
free(p1);
}
*head = NULL;
}
void main(void)
{
SLNode *head;
int i , x;
ListInitiate(&head);
for(i = 0; i < 10; i++)
{
if(ListInsert(head, i, i+1) == 0) /*insert ten data elements*/
{
printf("Error!! \n");
return;
}
}
if(ListDelete(head, 4, &x) == 0) /* delete data element 5*/
{
printf("error! \n");
return;
}
for(i = 0; i < ListLength(head); i++)
{
if(ListGet(head, i, &x) == 0) /* take out the element*/
{
printf("Error! \n");
return;
}
else printf("%d ", x); /* show data elements*/
}
Destroy(&head);
}
问题出在您的代码逻辑上。好的输出是 Code::Blocks 一个。
问题出在 insertNode
函数中。它的行为如下:它找到第 i-1 个节点并在它之后创建一个新节点。如果 i = 0
,第 0 个元素是在你的第一个循环的第一次迭代中找到的,之后不会有错误,因为 j = i - 1 = -1
。永远不要在你的代码中编辑头部的数据。
此外,每次调用 insertNode
函数时,您都会要求新节点的值为其位置 + 1.
所以你会得到这个:
---------- ----- -----
| random | ---> | 1 | ---> | 2 | ---> etc.
---------- ----- -----
head 0th 1st
之后,在 listGet
函数中,您对列表的制作方式产生了误解。例如,当调用 listGet(head, 0, &x)
时,条件 p->next != NULL && j < i
总是在第一次迭代时满足,这意味着返回的节点不是第 0 个,而是头。你应该改为写 :
j = -1; // 0 become -1
while(p->next != NULL && j < i)
{
p = p->next;
j++;
}
此外,您必须更改主循环中的边界。确实,listLength
returns 列表中元素的数量(这里是 10),但是索引不是从 1 bt 从 0 开始,这意味着你不能停在 10(因为有没有第 10 个节点)但在 9。因此你必须写:
for(i = 0; i < ListLength(head) - 1; i++)
{
if(ListGet(head, i, &x) == 0) /* take out the element*/
{
printf("Error! \n");
return 1;
}
else printf("%d ", x); /* show data elements*/
}
还有一点与此问题无关,但无论如何您都必须更正:您的 destroy 函数。
void Destroy(SLNode **head)
{
SLNode *p, *p1;
p = *head;
while(p != NULL)
{
p1 = p;
p = p->next;
/* make NULL assignment here */
p1->next = NULL;
free(p1);
}
/* head has been already freed in the above loop
* do not try to manipulate it */
// *head = NULL;
}