这是我今天参加考试的一个问题:
在C中,假设指针是严格类型的(即,指向int的指针不能用于指向char)。这是否会降低其表现力?如果不是,为什么以及如何补偿这种限制?如果有,怎么样?还有什么更多的结构可以用来“均衡”C的表达能力的丧失?
其他一些细节:
int x = 5; int *p = &x; char *temp = (char*)p;
(void*)
次转化我也在下面提到了我的答案。
答案 0 :(得分:5)
这是否意味着不再有void*
?如果是,那么是:C的表达力将是有限的,因为malloc
将无法实现。您需要在C ++ new
的精神中添加一个新的,类型化的免费商店分配机制。
(或者,否:C仍然是Turing-complete。但我不认为这就是这里的含义。)
实际上,C甚至没有图灵完备;见下面的评论。
答案 1 :(得分:2)
它实际上可能会提高C的表现力。 C是指定任何给定实现的少数语言之一不完整。标准中的类型表示将所有类型指定为char
的重叠数组,表示所有类型和程序可用的总数据(所有可能指针的空间,所有可能的文件名,以及所有可能的文件偏移量等是有限约束的,因此C的计算模型是有限状态机。
如果删除了指针被表示为char [sizeof (pointer type)]
的要求,那么正式指定的语言原则上可以处理无限量的数据,并且它将是图灵完备的。
答案 2 :(得分:1)
这是一个非常主观的问题。认为事实上我不知道“表达能力”是什么;)
仍然无法在指针类型之间进行转换是我头脑中的一大限制。似乎在使用Java映射时,char数组(例如来自网络套接字之类的东西)到类是非常烦人的。只需将其转换并重新解释内存的能力非常有用,并且可以在处理随机内存块时进行大量优化。
你如何解决这些限制?也许实现一个“强制转换”功能,或者只是一个可以重新解释内存的模板化memcpy函数,对于优化,对于像我这样的人来说,生产力是一个巨大的好处。它甚至可能是允许某种类“id”包含在字节流中的计划,以便您知道它可以被重新解释为特定的类。
拥有这种能力的缺点是它允许您以完全错误的方式解释数据。这可能会导致非常讨厌的错误。
答案 3 :(得分:1)
这个问题类似于询问指针强制转换的有用/有效用途。以下是一些:
如果没有指针强制转换,您必须拥有多个版本的memcpy
,memmove
,malloc
,因为这些版本都需要实现和使用指针转换。在malloc
的情况下,为用户定义的struct
分配内存变得不可能。
在稍微不同的类别中,您无法实现多态qsort
(标准库提供的那个对void*
数组进行排序,并且可以有效地用于对各种指针的数组进行排序)
关于什么样的功能可以重新获得表达能力,一个识别多态的类型系统,这样你就不必用不安全的指针转换编码它将是一个很好的步骤。 Languages of the ML family已经有了这种类型系统很长一段时间,如果你熟悉Java's generics,他们就会遵循同样的思路。
答案 4 :(得分:1)
我认为它不会降低它的表现力 - 你仍然可以写一个图灵机翻译,这意味着图灵完成了。例如,请参阅此code golf thread。
如果你的意思是在用户方便性方面具有表现力,那么它肯定会限制C很多,因为内存分配机制(malloc& co。)必须改变。
答案 5 :(得分:0)
在C中,假设指针是 严格键入(即指向 int不能用于指向a 炭)。
在C语言中提倡严格的指针输入完全失去了情节,这只是汇编语言的便携式简写。你认为能够射击自己,一个优秀的开发人员将足够聪明,不会。
答案 6 :(得分:0)
我想到了一种解决不能在各种类型之间进行类型转换的限制的方法。你可以使用一个联盟:
union alltypepointers
{
char* c,
short* s,
int* i,
float* f,
double* d,
...
};
所有指针的大小都相同,因此如果您更改了一个指针,则可以将其读取为任何其他类型。你也可以对这些指针进行算术运算:
int variable = 0x2345;
alltypepointers p;
p.i = &variable;
char *temp = p.c;
p.c++;
int newint=*p.i;
所以,你仍然可以做你之前可以做的所有事情=>表现力没有下降。
答案 7 :(得分:-3)
(someType *)((void *)somePtr)
该构造允许您将任何指针转换为(someType *)。