用C编写打印方法
我是C语言的新手,正在为Scheme做一个翻译。我试图获得一个合适的printList方法来遍历这个结构 该程序接收如下输入: (a(b)(c)) 并在内部表示为:用C编写打印方法,c,pointers,scheme,interpreter,C,Pointers,Scheme,Interpreter,我是C语言的新手,正在为Scheme做一个翻译。我试图获得一个合适的printList方法来遍历这个结构 该程序接收如下输入: (a(b)(c)) 并在内部表示为: [""][ ][ ]--> [""][ ][/] | | ["A"][/][/] [""][ ][ ]--> [""][ ][/] | |
[""][ ][ ]--> [""][ ][/]
| |
["A"][/][/] [""][ ][ ]--> [""][ ][/]
| |
["B"][/][/] ["C"][/][/]
现在,我只想让程序接收输入,在内部生成适当的单元格结构并打印出单元格结构,从而得到
(a(b)(c))
最后
这是我的结构:
typedef struct conscell *List;
struct conscell {
char symbol;
struct conscell *first;
struct conscell *rest;
};
void printList(char token[20]){
List current = S_Expression(token, 0);
printf("(");
printf("First Value? %c \n", current->first->symbol);
printf("Second value? %c \n", current->rest->first->first->symbol);
printf("Third value? %c \n", current->rest->first->rest->first->symbol);
printf(")");
}
在main方法中,我获取第一个令牌并调用:
打印列表(令牌)
我再次测试了子列表的值,我认为它是有效的。但是,我需要一种方法来遍历整个结构。请再次查看我的打印列表代码。打印调用是我必须键入的,以手动获取(a(b c))列表值。所以我得到了这个输出:
第一价值?a
第一价值?b
第一价值?c
这正是我想要的,但我想要一种使用循环的方法,不管结构有多复杂,也在适当的地方添加括号,所以最后,我应该得到:
(a(b)(c))
与输入相同
有人能帮我一下吗?列表的类型是struct conscell的指针,因此createList函数中的malloc()应该是sizeof(struct conscell): 指向结构的指针仅为8字节,而结构本身的大小为17(默认填充为24字节):
原始程序的数据类型有点奇怪;您希望能够描述一组不相交的数据,在这种情况下,联合可能就是您想要的。目前,cons单元格只有一个数据类型,这使得很难区分:
(a b c)
及
您现在使用的技巧是将符号数据视为单元格左右指针均为NULL的数据,但这使得无法表示:
(())
这正是当您有一个内容都为NULL的cons单元格时发生的情况
表示不相交数据集的一种方法是使用标记的不相交并集,如下所示:
enum SexpType {SYMBOL, CONS, NIL};
struct Sexp {
enum SexpType type;
union {
char symbol;
struct Cons *cons;
};
};
struct Cons {
struct Sexp *first;
struct Sexp *rest;
};
printf("(");
printSexp(sexp->cons->first);
printf(" . ");
printSexp(sexp->cons->rest);
printf(")");
Sexp可以是符号
、CONS
、或NIL
。根据其类型,我们将以不同的方式处理结构的联合部分
我们可能会包括一些助手,以便更容易地构建此类结构:
struct Sexp* newCons(struct Sexp* first, struct Sexp* rest) {
struct Sexp* pair = malloc(sizeof(struct Sexp));
pair->type = CONS;
pair->cons = malloc(sizeof(struct Cons));
pair->cons->first = first;
pair->cons->rest = rest;
return pair;
}
struct Sexp* newSymbol(char c) {
struct Sexp* ch = malloc(sizeof(struct Sexp));
ch->type = SYMBOL;
ch->symbol = c;
return ch;
}
一旦我们有了正确的数据表示,那么printList
将是一个递归函数,根据类型标记进行调度:
void printSexp(struct Sexp* sexp) {
switch (sexp->type) {
case SYMBOL:
/* FIXME */
break;
case CONS:
/* FIXME */
break;
case NIL:
/* FIXME */
break;
}
}
每种情况都相当简单。要让CONS
案例执行某些操作,我们可以尝试以下操作:
enum SexpType {SYMBOL, CONS, NIL};
struct Sexp {
enum SexpType type;
union {
char symbol;
struct Cons *cons;
};
};
struct Cons {
struct Sexp *first;
struct Sexp *rest;
};
printf("(");
printSexp(sexp->cons->first);
printf(" . ");
printSexp(sexp->cons->rest);
printf(")");
我们递归调用打印机对的组件。但是,这可能不是我们想要的,因为它将所有内容都视为不正确的结构,您可能希望为常规列表做一些更好的事情。列表的类型是struct conscell的指针,因此malloc的大小应为sizeof(struct conscell)…非常感谢您在修复此问题时提供的帮助。现在它更有意义了。您还可以查看更新后的问题,看看是否可以找到根本问题吗?@RehanRasool在如上所述修复分配大小后,您可能还需要插入程序中的内存泄漏
List
是指针类型,并且temp=createList()代码>紧跟其后的是temp=local代码>是两行短的直接内存泄漏。@WhozCraig很好。我只是在看createList()函数。@RehanRasool您也可以发布getToken()函数和程序的主要方法吗?函数S_表达式中的strcpy也有点令人担忧…@tanukisotware我认为这将是很多您可能不想了解的信息。getToken只获取输入行中的下一个字符串。例如,如果我输入:(abc)第一个strcpy(token,getToken)调用,则复制('到令牌。下次,它将'a'复制到令牌,下次将'b'复制到令牌等等。如果您仍然想看到它,我可以上传它。其次,现在作业不需要我处理内存丢失问题,所以我不担心。感谢您到目前为止的回复!