【发布时间】:2015-07-11 15:45:34
【问题描述】:
我会尽量说清楚。
我在一个名为“esercizio.h”的文件中有这个结构(由于我的老师,我无法更改它):
#ifndef ESERCIZIO_H
#define ESERCIZIO_H
struct ElemSCL{
int info;
struct ElemSCL* next;
};
typedef struct ElemSCL NodoSCL;
typedef NodoSCL* TipoSCL;
void accoda(TipoSCL* pscl, int i);
#endif
函数“accoda”必须将一个元素 (int i) 添加到循环链表的末尾(由 TipoSCL* pscl 指向)。我试图在一个名为“esercizio.c”的文件中编写函数体:
#include <stdio.h>
#include <stdlib.h>
#include "esercizio.h"
void accoda(TipoSCL* pscl, int i){
NodoSCL* temp = (NodoSCL*) malloc(sizeof(NodoSCL));
temp->info = i;
temp->next = temp;
if (pscl == NULL){
return;}
while ((*pscl)->next != *pscl){
*pscl = (*pscl)->next;}
(*temp)->next = (*pscl)->next; //Problems starts here
(*pscl)->next = *temp;
}
正如我在代码中让您注意到的,如果我不添加最后两行,一切都会好起来的。如果函数中没有 TypeSCL* 而是 NodeSCL* 我会使用:
temp->next = pscl->next;
pscl->next = temp;}
但我的老师决定使用 TypeSCL* pscl 而不是 NodeSCL* pscl。
我有一个“test.h”文件...
#include "esercizio.h"
#ifndef TEST_H
#define TEST_H
char* toString(TipoSCL scl);
#endif
... 和一个“test.c”文件,其中包含 main() 函数和所有让我检查我的代码是否正常工作的输入:
#include <stdlib.h>
#include <string.h>
#include "../libtest/libtest.h"
#include "test.h"
#include "esercizio.h"
const int NTEST=5;
TipoSCL input[5];
int add[5] = {1,2,3,4,5};
TipoSCL expected[5];
int main(int argc, char** argv){
input[0] = NULL;
input[1] = (TipoSCL) malloc(sizeof(NodoSCL));
input[1] -> info = 1;
input[1] -> next = input[1];
input[2] = (TipoSCL) malloc(sizeof(NodoSCL));
input[2] -> info = 1;
input[2] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[2] -> next -> info = 2;
input[2] -> next -> next = input[2];
input[3] = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> info = 1;
input[3] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> next -> info = 2;
input[3] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[3] -> next -> next -> info = 3;
input[3] -> next -> next -> next = input[3];
input[4] = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> info = 1;
input[4] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> info = 2;
input[4] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> next -> info = 3;
input[4] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
input[4] -> next -> next -> next -> info = 4;
input[4] -> next -> next -> next -> next = input[4];
expected[0] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[0] -> info = 1;
expected[0] -> next = expected[0];
expected[1] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[1] -> info = 1;
expected[1] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[1] -> next -> info = 2;
expected[1] -> next -> next = expected[1];
expected[2] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> info = 1;
expected[2] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> next -> info = 2;
expected[2] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[2] -> next -> next -> info = 3;
expected[2] -> next -> next -> next = expected[2];
expected[3] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> info = 1;
expected[3] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> info = 2;
expected[3] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> next -> info = 3;
expected[3] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[3] -> next -> next -> next -> info = 4;
expected[3] -> next -> next -> next -> next = expected[3];
expected[4] = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> info = 1;
expected[4] -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> info = 2;
expected[4] -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> info = 3;
expected[4] -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> next -> info = 4;
expected[4] -> next -> next -> next -> next = (TipoSCL) malloc(sizeof(NodoSCL));
expected[4] -> next -> next -> next -> next -> info = 5;
expected[4] -> next -> next -> next -> next -> next = expected[4];
test_reset();
for (int i = 0; i < NTEST; i++) {
print_test_start(i+1);
printf("Funzione: accoda\n");
printf("Input: %s\n", toString(input[i]));
accoda(&input[i],add[i]);
test_compare_strings(toString(expected[i]),toString(input[i]));
print_test_end();
print_n_success("#Test superati: ");
}
print_test_result("Percentuale test corretti:");
}
char* toString(TipoSCL scl){
char* res = (char*) malloc(200*sizeof(char));
res[0] = '[';
res[1] = '\0';
TipoSCL aux = scl;
if (aux != NULL) {
char buf[10];
do{
sprintf(buf,"%d->",aux -> info);
strcat(res,buf);
aux = aux -> next;
}
while(aux != scl);
sprintf(buf,"|%d",aux -> info);
strcat(res,buf);
aux = aux -> next;
}
strcat(res,"]");
return res;
}
“如果我不将最后两行添加到代码中,一切正常”是什么意思? 当我在没有
的情况下运行我的程序时(感谢终端和 cd 和 make )(*temp)->next = (*pscl)->next; //Problems starts here
(*pscl)->next = *temp;
测试运行没有问题(当然,它说我没有一个正确的结果。但是如果我将这两行添加到我的代码中,我会得到“分段错误:11”。
【问题讨论】:
-
根据您调用
add的方式,*pscl可能指向列表的head。除此之外,当你说“事情出错了......”时,你的意思是什么?你能详细说明一下吗?你有构建错误吗?运行时错误?意外行为?什么?请尝试创建一个Minimal, Complete, and Verifiable Example 并向我们展示,包括您如何调用add函数以及您传递的参数。 -
temp->next = temp;这行是不必要的,因为接下来您要做的就是再次更改 temp->next。此外,由于 *pscl 也是一个指针,因此最好检查它是否为空。我会将if(pscl == NULL)更改为if(pscl == NULL || *pscl == NULL) -
标准警告:不要像
malloc和朋友使用的那样投射void *。 -
为指针创建类型通常是个坏主意。这使得代码阅读起来更加复杂并增加了混乱,因为您必须记住额外的间接性。最好为指针变量显式添加
*。 -
好吧,如果你必须添加到列表的末尾,你不应该使用while循环遍历到最后一个节点吗?该列表可能会超过大小 2
标签: c list linked-list circular-list