我是C的新手,正在为Scheme制作翻译。我试图获得一个合适的printList方法来遍历结构。
该程序接受如下输入:
(a(b c))
并在内部将其表示为:
[""][ ][ ]--> [""][ ][/]
| |
["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方法中,我得到第一个令牌并调用:
的printList(令牌);
我再次为子列表测试了值,我认为它正在运行。但是,我需要一种方法来遍历整个结构。请再次查看我的printList代码。打印调用是我必须键入的,手动获取(a(b c))列表值。所以我得到了这个输出:
第一个值?一个
第一个值? B'/ P>
第一个值? ç
这就是我想要的,但是我想要一个使用循环的方法,无论结构有多复杂,还要在适当的地方添加括号,所以最后,我应该得到:
(a(b c))
与输入相同。
有人可以帮我解决这个问题吗?
答案 0 :(得分:2)
原始程序的数据类型有点奇怪;您希望能够描述一组不相交的数据,在这种情况下,联合可能就是您想要的。目前,您只有一个cons单元格的数据类型,这使得很难区分:
(a b c)
和
(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;
};
Sexp可以是SYMBOL
,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
案例做某事,我们可能会尝试这样的事情:
printf("(");
printSexp(sexp->cons->first);
printf(" . ");
printSexp(sexp->cons->rest);
printf(")");
我们以递归方式调用打印机上的组件。但是,这可能不是我们想要的,因为它将所有内容视为不正确的结构,并且您可能希望为常规列表做更好的事情。
答案 1 :(得分:1)
List的类型是struct conscell的指针,因此createList函数中的malloc()应该是sizeof(struct conscell):
List node = malloc(sizeof(struct conscell));
指向结构的指针只有8个字节,而结构本身的大小为17(默认填充实际为24byte):