免责声明:我是一名学习 C 的 Haskell 程序员。在 Haskell 中,我们有如下数据声明
data No = NO
其中 NO 没有任何数字解释。如果我们在 C 中有等价的东西,我们可以做
union MaybeInt { enum No no; int just;};
它可以用来做一些事情,比如有一个初始化为 No 的数组。
int A[k];
for (int i = 0; i < k; i++)
A[i] = NO;
这在做记忆时很有用,因为通常有一些递归算法,它在数组中查找事物并基于查找的值,进行递归调用或不进行调用。例如:(对于斐波那契数)
fibMem (int k){
if (FIB[k] == NO)
compute fibMem(k-1) + fib(k-2) and store the result in FIB[k]
return FIB[k]
}
现在,当然,我可以将 FIB[i] 初始化为一些荒谬的值,例如 -100,这适用于这个问题;但是,给定一个任意的记忆例程,我不知道值的范围,这种解决方案是行不通的。
使用枚举类型的问题:我看到的第一件事就是让我从座位上跳起来说“是”是枚举类型。我想为什么不做类似的事情呢enum No {no};
,用 s 初始化用于记忆的数组有问题no
。问题是,如果我愿意,它no
被定义为0
或我选择的某个数字常数。这是不令人满意的,因为如果存储在数组中的值应该为零(或我选择的那个常数),那么当我进行检查时A[i] == no
,它可能应该是这样的!因此,我最终将执行不需要的递归。
这给我们带来了问题 1:如何在 C 中获得一个被视为标志的符号常量,它与任何不同类型的东西都无法比较?
现在,工会的问题。联合将其所有字段存储在一个地址中。因此,例如,对maybeInt.just 的更新会影响mayInt.no 的值。例如,
union MaybeInt maybeInt;
maybeInt.just=9;
printf("%d",maybeInt.just);
printf("%d",maybeInt.no);
打印 99。如果 C 中有某种不相交的联合类型,那么如果我使用联合的一个值,另一个将变得无法获得。
这给我们带来了第二个也是最后一个问题:如何在 C 中获得不相交的联合类型——这种类型有许多可能的变体,但在任何给定时间只有一个变体。我想要一些能够做类似的事情:
disjoint T {type1 name1 , .... };
并设置了 if T.name2,然后对 T.name1 的引用会引发错误。或者更好的是,任何对 T 的引用都必须经过某种大小写区分。
如果这不能很好地完成,请解释原因。