假设我们分别在Algol 68和C中有以下说明:
ref int x := 5;
和(int*) x = 5;
。它们的语义差异是什么?,它是一样的吗?因为我认为第二个说“x将指向一个常量”(它无法编译),第一个说“x将指向一个记忆”指向包含常量5“的另一个存储单元的单元格。这是正确的吗?如果没有,你能解释一下并举一些例子来理解这个吗?
答案 0 :(得分:4)
我不假装成为Algol 68(或Algol 60)专家 - 我从未使用任何一种语言编写任何内容。
然而,维基百科Algol 68 mode declarations说:
然而,声明
real x;
只是ref real x = loc real;
的语法糖。也就是说,x
实际上是新生成的本地real
变量的引用的常量标识符。
鉴于这个解释,问题是Algol片段:
ref int x := 5;
对应于(或多或少)C代码:
int *x = malloc(sizeof(*x));
*x = 5;
抛开错误检查和释放已分配内存的问题。
问题的C片段:
(int *)x = 5;
很大程度上没有意义 - 演员表的结果不是可修改的左值,你只能指定一个可修改的左值。如果重写为:
int x_data;
int *x = &x_data;
*(int *)x = 5;
然后它变为有效的C,尽管演员阵容完全是多余的。当然,也可以编写它来使用内存分配。在C中,使用x
访问整数值(而不是指针)需要在C(*x
或x[0]
)中取消引用。相比之下,在Algol 68中,没有必要明确地取消引用变量x
。
虽然问题提到了“常数”几次,但我没有看到任何暗示代码中的持久性。值5
被分配给位置中的变量。存储在该位置的值可以稍后通过另一个分配进行更改。
问题标题询问了关于强制转换的问题,但是我没有看到Algol代码中存在强制转换的证据,并且不清楚为什么在C代码中认为有必要使用强制转换。
答案 1 :(得分:3)
Algol 68根据具体情况(强,坚,弱,弱和软背景)提供许多隐式强制:cf Wikipedia & Algol68's Coercion Hierarchy。
Algol68可以隐式处理:
C强化具有更多受限制的隐式投射:
float
到int
仅在某些情况下。扩展到数组需要指针和手动编码使用"&"操作者。带输出的示例代码......
文件:deref_and_cast.c
#include <stdio.h>
#include <stdlib.h>
main(){
auto int*** crrri;
crrri=(int***)malloc(sizeof(int**));
*crrri=(int**)malloc(sizeof(int*));
**crrri=(int*)malloc(sizeof(int));
***crrri=255; /* coder to explicitly work out how many times dereference */
printf("%5.1f\n",(float)***crrri); /* Again deref is muilt-explicit */
}
<强>输出:强>
255.0
档案:coerce_and_cast.a68
#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
LOC REF REF REF INT crrri;
REF REF REF REF INT(crrri):=HEAP REF REF INT;
REF REF REF INT(crrri):=HEAP REF INT;
REF REF INT(crrri):=HEAP INT;
REF INT(crrri):=255; # targeted dereferencing (3x) depending on contect #
printf(($"example meek coercion:"g(-5,1)l$,REAL(crrri)));
隐式强制的层次结构示例
PROC VOID raise exception = end; # Implicitly cast a "GO TO" to a PROC #
# Soft: deprocedure a PROC to a VALUE #
printf(($"Soft:"gl$,random)); # Implicit Coercion #
printf(($"Soft:"gl$,REAL(random))); # Explicitly cast/deprocedure #
# Weak: dereference pointer chain to a "name" (LHS in C lingo) #
COMPL compl:= 0;
re OF compl := crrri; # Implicit Coercion #
REF REAL(re OF compl) := crrri; # Explicitly cast/dereference #
printf(($"Weak:"g(-0,4)g(7,4)"i"l$,compl));
# Meek: dereference to a value #
printf(($"Meek:"gl$,sin(crrri))); # Implicit Coercion #
printf(($"Meek:"gl$,sin(REAL(crrri)))); # Explicitly cast/dereference #
# Firm: unite to a UNION #
MODE IRC=UNION(INT,REAL,COMPL);
OP SIN = (IRC z)IRC: (z|(INT i):sin(i),(REAL r):sin(r),(COMPL z):complex sin(z));
printf(($"Firm:"gl$,SIN 1)); # Implicit Coercion #
printf(($"Firm:"gl$,SIN IRC(1))); # Explicitly cast/unite #
# Strong: widen to higher precision OR to an array #
FLEX [0]BOOL bool array := BIN crrri; # Implicit Coercion #
bool array := []BOOL(BIN crrri); # Explicitly cast/widen #
printf(($"Strong:"$,$g$,bool array,$l$));
end: SKIP
<强>输出:强>
example meek coercion:255.0
Soft:+2.11679610884246e -1
Soft:+4.01945464342605e -1
Weak:255.0000+0.0000i
Meek:-5.06391634924491e -1
Meek:-5.06391634924491e -1
Firm:+8.41470984807897e -1
Firm:+8.41470984807897e -1
Strong:FFFFFFFFFFFFFFFFFFFFFFFFTTTTTTTT
答案 2 :(得分:1)
Algol68对“名称”(与“标识符”不同)的含义采取了严格的方法。一个明显的结果是,Algol68在对象的类型/模式上倾向于具有比其他语言更多的引用。
因此INT
是一个常量整数的模式(它甚至可能不需要在运行时分配内存)。 REF INT
是“整数变量”的模式,而REF REF INT
是“引用整数变量”的模式。
INT x = 42;
REF INT y = LOC INT := x;
REF REF INT z = LOC REF INT := y;
LOC是一个“本地生成器”,实际上只是分配堆栈空间并返回其“名称”(即地址)。
(请注意,'='建立等效性,':='则是赋值)
熟悉语法所需要的是,这两个变量声明可以使用缩写形式:
INT y := x;
REF INT z := y;
但是y
的模式仍然是REF INT
,依此类推。IMO,缩写是个坏主意。
C当量
#define x 42
int y = x;
int* z = &y;