Mar*_*ins 17
这是一个我以前没见过的有趣的想法.凭借今天相当丰富的内存,它看起来很复杂,但收益微不足道(尽管不是所有平台都充满了内存). 编辑在完成我的实际工作时,我的思绪一直在回归,所以我添加了创建新节点的功能并将其放在给定的一端.现在比较漂亮.addnode和traverse函数都是对称的,这很酷.两者都不需要知道方向.只需给它列表的一端,它们就能正常运行.
根据Darron的评论(谢谢),我将int更改intptr_t为可移植性.
#include <stdio.h>
#include <malloc.h>
#include <stdint.h> // gcc needs this for intptr_t.
typedef struct xorll {
int value;
struct xorll *np;
} xorll;
// traverse the list given either the head or the tail
void traverse( xorll *start ) // point to head or tail
{
xorll *prev, *cur;
cur = prev = start;
while ( cur )
{
printf( "value = %d\n", cur->value );
if ( cur->np == cur )
// done
break;
if ( cur == prev )
cur = cur->np; // start of list
else {
xorll *save = cur;
cur = (xorll*)((uintptr_t)prev ^ (uintptr_t)cur->np);
prev = save;
}
}
}
// create a new node adding it to the given end and return it
xorll* newnode( xorll *prev, xorll *cur, int value )
{
xorll *next;
next = (xorll*)malloc( sizeof( xorll ));
next->value = value;
next->np = cur; // end node points to previous one
if ( cur == NULL )
; // very first node - we'll just return it
else if ( prev == NULL ) {
// this is the second node (they point at each other)
cur->np = next;
next->np = cur;
}
else {
// do the xor magic
cur->np = (xorll*)((uintptr_t)prev ^ (uintptr_t)next);
}
return next;
}
int main( int argc, char* argv[] )
{
xorll *head, *tail;
int value = 1;
// the first two nodes point at each other. Weird param calls to
// get the list started
head = tail = newnode( NULL, NULL, value++ );
tail = newnode( NULL, tail, value++ );
// now add a couple to the end
tail = newnode( tail->np, tail, value++ );
tail = newnode( tail->np, tail, value++ );
// this is cool - add a new head node
head = newnode( head->np, head, 999 );
printf( "Forwards:\n" );
traverse( head );
printf( "Backwards:\n" );
traverse( tail );
}
Run Code Online (Sandbox Code Playgroud)
由于无法对指针执行xor操作,因此必须将地址转换为整数类型以执行xor并将结果转换回右指针类型.
据我所知,C99只有两种整数类型,可以保证转换到具有已定义行为的指针(=将原始指针返回):intptr_t和uintptr_t来自<stdint.h>.请注意,这两种类型都是可选的,因此您的实现可能没有它们.
转换示例,假设a并且b是有效指针struct node:
#include <stdint.h>
/* creating an xor field */
uintptr_t x = (uintptr_t) (void *) a ^ (uintptr_t) (void *) b;
/* reconstructing an address */
a = (void *) (x ^ (uintptr_t) (void *) b);
Run Code Online (Sandbox Code Playgroud)
我不是100%确定void *需要额外的演员表,如果他们不是,请有人纠正我.有关(u)intptr_t类型的更多信息,请参见C99标准的§7.18.1.4 .