【发布时间】:2020-11-25 15:26:13
【问题描述】:
从这些问题:Casting one struct pointer to another - C,我想知道,是否可以使用类型为“特定”结构的“一般”结构的成员:
#include <stdio.h>
#include <stdlib.h>
enum type_e { CONS, ATOM, FUNC, LAMBDA };
typedef struct {
enum type_e type;
} object;
typedef struct {
enum type_e type;
char *expression;
} lambda_object;
typedef struct {
enum type_e type;
object *car, *bus;
int value;
} cons_object;
object *traverse(object *o){
if (o->type == CONS){
cons_object *cons = (cons_object*)o;
traverse(cons->car);
traverse(cons->bus);
return (object*)cons;
} else if (o->type == LAMBDA) {
lambda_object *lam = (lambda_object*)o;
return (object*)lam;
}
return 0;
}
int main(){
lambda_object l = {LAMBDA, "value to print\n"};
object *p = traverse((object*)&l);
printf("sizeof(object):%lu\nsizeof(lambda_object):%lu\n",sizeof(object), sizeof(lambda_object));
printf("%s\n",*(p+4));
}
没有错误,只是command terminated,所以我不知道出了什么问题,但怀疑我试图推迟错误的地址*(p+4),但我知道,有一个指向我的字符串的指针。从lambda_object的定义,在enum(4字节长,和int一样)之后,有我的指针。所以我不应该取消引用错误的地址,但我仍然不能。为什么?
输出:
a.c: In function ‘main’:
a.c:46:11: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘object’ {aka ‘struct <anonymous>’} [-Wformat=]
printf("%s\n",*(p+4));
~^ ~~~~~~
Press ENTER or type command to continue
sizeof(object):4
sizeof(lambda_object):16
Command terminated
编辑:
我试过(char*)p[4],还是终止
【问题讨论】:
-
这就是
union的用途。 -
指针运算不是这样工作的。
p+4在p之后指向struct object类型的4 个元素。这与p[4]完全相同。 -
如果
sizeof(object)不是 1(可能是这种情况,因为它包含一个可能存储为int的枚举),那么(p+4)是一个距离 p 4 个字节的指针。如果这就是您想要的,请使用((char)p + 4)。但它是丑陋的编程,容易出错。更好的是使用union来定义占用相同空间的结构。 -
@milanHrabos 和
p[4]你犯了和以前一样的错误![]比强制绑定更紧密(具有更高的优先级)。是什么阻止您使用((lambda_object*)p)->expression之类的东西? -
我不清楚你想要达到什么目的。也许如果您描述有人可以提出更好的方法。在这里,您正在玩火并做出不成立的假设。无论如何 - 只是为了好玩 - 试试:
printf("%s\n", *(char**)((char*)p + ((unsigned long long)&l.expression - (unsigned long long)&l)));
标签: c struct casting type-conversion