gpt4 book ai didi

c - 如何通过空指针访问成员

转载 作者:太空宇宙 更新时间:2023-11-04 01:36:33 25 4
gpt4 key购买 nike

开始尝试编写一个小程序将基本算术翻译成英语,最后我构建了一个二叉树(这不可避免地非常不平衡)来表示评估的顺序。首先,我写了

struct expr;

typedef struct{
unsigned char entity_flag; /*positive when the oprd
struct represents an entity
---a single digit or a parenthesized block*/
char oprt;

expr * l_oprd;// these two point to the children nodes
expr * r_oprd;
} expr;

但是,为了有效地表示单个数字,我更喜欢

typedef struct{
unsigned char entity_flag;
int ival;
} digit;

由于现在每个“expr”结构的“oprd”字段可能是上述结构中的任何一个,我现在将它们的类型修改为

void * l_oprd;
void * r_oprd;

接着就是“中心问题”: 如何通过 void 指针访问成员?请看下面的代码

#include<stdio.h>
#include<stdlib.h>


typedef struct {
int i1;
int i2;} s;
main(){
void* p=malloc(sizeof(s));

//p->i1=1;
//p->i2=2;

*(int*)p=1;
*((int *)p+1)=2;
printf("s{i1:%d, i2: %d}\n",*(int*)p,*((int *)p+1));
}

编译器不会接受注释版本!我是否必须使用上述困惑的方法来完成?

请帮忙。

PS:如您所见,上面的每个结构体都有一个名为“entity_flag”的字段,因此

void * vp;
...(giving some value to vp)
unsigned char flag=vp->entity_flag;

可以提取标志,而不管 void 指向什么,这在 C 中允许吗?甚至是 C 中的“安全”?

最佳答案

您不能通过void * 指针访问成员。您可以通过多种方式转换它(事实上,您甚至不需要使用 void * 明确说明情况),但即使这样也是错误的答案.

正确答案是使用union:

typedef union {
struct{
unsigned char entity_flag; /*positive when the oprd
struct represents an entity
---a single digit or a parenthesized block*/
char oprt;

expr * l_oprd;// these two point to the children nodes
expr * r_oprd;
} expr;
struct{
unsigned char entity_flag;
int ival;
} digit;
} expr;

然后您可以像这样访问一个表达式(给定一个变量 expr *e):

e->expr->entity_flag;

像这样的数字:

e->digit->entity_flag;

任何其他解决方案都是令人讨厌的 hack,IMO,并且大多数强制转换解决方案都有违反“严格别名”规则的风险,该规则规定允许编译器假定两个不同类型的指针不能引用相同的内存.


编辑...

如果您需要能够检查数据本身以找出正在使用 union 体的哪个成员,则可以。

基本上,如果两个结构中的最顶层字段被声明为相同,那么它们将具有相同的二进制表示。这不仅限于 union ,在为该架构编译的所有二进制文件中通常都是如此(如果您考虑一下,这对于库的工作至关重要)。

在 union 中,通常将它们拉出到一个单独的结构中,这样很明显你在做什么,尽管这不是必需的:

union {
struct {
int ID;
} base;
struct {
int ID;
char *data
} A;
struct {
int ID;
int *numeric_data;
} B;
}

本方案中p->base.ID,p->A.ID,p->B.ID是有保证的阅读相同的内容。

关于c - 如何通过空指针访问成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13454433/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com