Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的uintptr\t和intptr\t_C_Pointers_Memory Address - Fatal编程技术网

C语言中的uintptr\t和intptr\t

C语言中的uintptr\t和intptr\t,c,pointers,memory-address,C,Pointers,Memory Address,当我在研究XOR链表时,我遇到了一个名为intptr\u t/uintptr\u t的类型,我知道我们可以将指针强制转换为该类型,并将其作为整数进行操作,但没有问题 如果…怎么办 我们确实有一个变量inta(假设它的地址是100), 这行(int*x=(intptr\u t)100)是否意味着x指向a?如果不是,那么它做什么呢 提前感谢。int*x=(intptr\t)100完全是胡说八道,它不是有效的C,而是编译器必须抱怨的约束冲突。有关详细信息,请参阅 也许你的意思是int*x=(intpt

当我在研究XOR链表时,我遇到了一个名为
intptr\u t
/
uintptr\u t
的类型,我知道我们可以将指针强制转换为该类型,并将其作为整数进行操作,但没有问题 如果…怎么办 我们确实有一个变量
inta
(假设它的地址是100), 这行(
int*x=(intptr\u t)100
)是否意味着
x
指向
a
?如果不是,那么它做什么呢

提前感谢。

int*x=(intptr\t)100
完全是胡说八道,它不是有效的C,而是编译器必须抱怨的约束冲突。有关详细信息,请参阅

也许你的意思是
int*x=(intptr\u t*)100
?在这种情况下,指针转换无效-也不允许

100
强制转换为
intptr
是没有意义的,因为
100
已经是一个整数了。当您有一个指针并且需要一个表示该指针中存储的地址的整数时,可以使用
intptr

如果您希望根据硬件寄存器或内存位置的绝对地址来访问它,那么这里有一个详细的指南:。

XOR链表方法是一种构造链表的方法,可以使用单个指针的空间在两个方向上导航。诀窍是在
链接
成员中存储下一个和上一个项目地址的异或,将这些地址转换为
uintpr\u t
(或
intptr\u t
)值,对适当大小的整数执行位异或,并将此信息存储为整数:

struct项{
uintptr_t link;
int data;//项负载。可以是任意类型的任意数量的成员
};
如果您知道上一项(或下一项)的地址,则可以从两个方向遍历列表:

struct item*get_链接(struct item*p,const struct item*previous){
返回(结构项*)(p->link^(uintptr\t)上一个);
}
为避免出现有关对齐问题的警告,您可能需要添加额外的强制转换为:

return (struct item *)(void *)(p->link ^ (uintptr_t)previous);
uintpttr\u t
是一个整数类型,指定为具有与
void*
相同的大小,因此可以包含来自任何数据指针的所有信息。将数据指针转换为
uintptr\u t
并使用强制转换返回应该会产生相同的指针

intptr\u t
是相应的有符号类型,其本身用处不大

XOR链表黑客现在主要是历史感兴趣的。唯一的优点是体积小,几乎不值得增加复杂性。如果需要在两个方向上扫描列表,那么使用常规的双链接列表要好得多。使用此技巧的扫描需要在遍历方向上保持指向当前项和前一项的指针,而常规双链接列表可以用单个指针处理,因此可以以更简单的方式进行操作和/或共享

下面是一个示例实现:

#包括
#包括
#包括
结构项{
uintptr_t link;
int data;//项负载。可以是任意类型的任意数量的成员
};
结构异或列表{
结构项*头;
结构项*尾部;
};
结构项*获取链接(结构项*ip,常量结构项*上一个){
返回(结构项*)(ip->link^(uintptr\t)上一个);
}
结构项*获取下一个(结构项*ip,结构项**上一个){
结构项*下一个=获取链接(ip,*上一个);
*先前=ip;
下一步返回;
}
uintptr生成链接(结构项*上一个,结构项*下一个){
返回(uintptr)上一个^(uintptr)下一个;
}
结构项*添加项(结构异或列表*lp,整数数据){
结构项*ip=malloc(sizeof(*ip));
如果(ip){
结构项目*tail=lp->tail;
ip->data=数据;
如果(尾部){
结构项*prev=get_链接(lp->tail,空);
ip->link=make_link(尾部,空);
尾部->链接=建立链接(上一个,ip);
lp->tail=ip;
}否则{
ip->link=make_link(空,空);
lp->head=lp->tail=ip;
}
}
返回ip;
}
int main(){
结构xor_列表={NULL,NULL};
结构项*ip,*prev;
添加项目(&列表,1);
添加_项(&列表,2);
添加_项(&列表,3);
添加_项(&列表,4);
添加_项(&列表,5);
printf(“从头到尾的遍历:”;
for(prev=NULL,ip=list.head;ip;ip=get_next(ip,&prev)){
printf(“%d”,ip->数据);
}
printf(“\n”);
printf(“从尾部到头部的遍历:”;
for(prev=NULL,ip=list.tail;ip;ip=get_next(ip,&prev)){
printf(“%d”,ip->数据);
}
printf(“\n”);
返回0;
}

XOR链表黑客现在主要是历史感兴趣的。唯一的优点是体积小,几乎不会比增加的复杂性更糟。如果需要从两个方向扫描列表,最好使用常规的双链接列表。如果
a
存储在地址
100
(即
printf('%p',&a)
prints
0x64
),则
int*x=(int*)100
应使
x
指向与
a
相同的地址。因此,这是一种复杂的、不可移植的方式来执行
int*x=&a。但是写
int*x=(intptr\u t)100
没有意义,因为
intptr\u t
是一个数字,
int*
是一个指针。如果您想检查指针的值,像
intptr\u t x=(intptr\u t)&a这样的东西是有意义的。如果你需要检查指针的值,有99.9%的几率你做错了什么。“我知道我们可以将指针转换为这种类型,并将其作为整数进行操作,不会出现任何问题”-->1)对对象指针很有用。尝试使用函数指针可能会丢失信息。2) 
intptr\u t/uintpttr\u t
是常见的可选类型,具有兼容的编译器。3) 指针的转换应通过