我通常不会编写C ++代码,但我的一个奇怪的comp sci朋友厌倦了查看我精彩的FORTRAN程序并挑战我用C ++重写其中一个,因为他更喜欢我的C ++代码。 (我们在这里投入资金。)确切的条款是它需要在现代C ++编译器中进行编译。也许他讨厌一个好的conio.h - 我不知道。
现在我意识到在C ++中有很好的写作方式,但是我想通过尽可能使我的C ++版本成为FORTRAN-esque来获得个人胜利。对于奖励积分,当我转换代码时,这可能会节省一些时间和精力。
SO!这让我想到了以下相关问题:
关于getos:
在longjmp上:
现在我主要担心的是为此计算goto。看起来我可能会使用longjmp来完成这项工作,因为void指针数组不属于C ++标准,但是GCC特定的扩展。
答案 0 :(得分:7)
我会咬人并采取行动。
我非常怀疑你的朋友会发现使用C ++编写的Fortran更容易(如果你使用goto和longjmp,这将是你将得到的),他甚至可能会发现它更难以理解。 C ++语言与Fortran有很大不同,我认为你不应该尝试从Fortran到C ++的直接转换。它只会让C ++更难维护,你可以继续使用现有的代码库。
goto
:您设置了一个标签(my_label:
),然后使用goto命令goto my_label;
,这将导致您的程序流在goto之后的语句中执行。您无法跳过变量的初始化或函数之间的跳转。您无法创建goto
目标数组,但可以创建一个对象或函数指针数组以跳转到。
longjmp
:如果您只有一个功能,则没有理由更喜欢longjmp
而不是goto
。但是,如果你只有一个函数,那么你真的不是在编写C ++,从长远来看,只要维护你的Fortran你会更好。
答案 1 :(得分:4)
你会得到很多关于使用goto
的haterade。通常情况下,我会直接赶上潮流,但在这种特殊情况下,它听起来更像是高尔夫球。所以,你走了。
使用goto
将指令指针移动到代码中的“标签”,这是一个C ++标识符,后跟一个冒号。这是一个工作程序的简单示例:
#include <iostream>
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int i = 0;
step:
cout << "i = " << i;
++i;
if( i < 10 )
goto step;
}
在这种情况下,step:
是标签。
有关于背景的担忧。
goto
到当前功能中的标签。goto
跳过了变量的初始化,你可能会唤起Undefined Behavior(将编译的代码,但你不能确定它实际会做什么。)。goto
进入try
块或catch
处理程序。但是,可以 goto
out try
块。如果满足其他问题,您可以使用指针等“转到”。如果有问题的指针在调用站点的范围内,并且在分支站点的范围内,则没问题。
答案 2 :(得分:3)
答案 3 :(得分:3)
goto
- &gt; switch
实际上,他们共享一个(常见的,但不是通用的)基础实现作为跳转表。
答案 4 :(得分:1)
如果我理解原始问题,那么问题实际上是一个有趣的问题。重写问题(我认为是一个等价的问题):“你如何在C中进行FORTRAN计算goto?”
首先我们需要知道计算的goto是什么:这是一个解释的链接:http://h21007.www2.hp.com/portal/download/files/unprot/fortran/docs/lrm/lrm0124.htm。
计算GOTO的一个例子是:
GO TO (12,24,36), INDEX
其中12,24和36是声明编号。 (C语言标签可以作为等价物,但不是唯一可以等同的东西。)
INDEX是一个变量,但可能是公式的结果。
这是在C中做同样事情的一种方式(但不是唯一的方法):
int SITU(int J, int K)
{
int raw_value = (J * 5) + K;
int index = (raw_value % 5) - 1;
return index;
}
int main(void)
{
int J = 5, K= 2;
// fortran computed goto statement: GO TO (320,330,340,350,360), SITU(J,K) + 1
switch (SITU(J,K) + 1)
{
case 0: // 320
// code statement 320 goes here
printf("Statement 320");
break;
case 1: // 330
// code statement 330 goes here
printf("Statement 330");
break;
case 2: // 340
// code statement 340 goes here
printf("Statement 340");
break;
case 3: // 350
// code statement 350 goes here
printf("Statement 350");
break;
case 4: // 360
// code statement 360 goes here
printf("Statement 360");
break;
}
printf("\nPress Enter\n");
getchar();
return 0;
}
在这个特定的例子中,我们看到你不需要C gotos来实现FORTRAN计算的goto!
答案 5 :(得分:0)
Longjmp可以让你走出一个很好的信号处理程序 - 它会增加一些混乱,因为它不会在它跳转到setjmp行之前定义的函数中重置自动(基于堆栈)变量。 :)
答案 6 :(得分:0)
有一个名为 Labels as Values 的GCC扩展程序可以帮助您编写高尔夫代码,实际上是为您提供计算goto。当然,您可以自动生成标签。您可能需要这样做,因为您无法知道每行将生成多少字节的机器代码。