繁体   English   中英

将指针作为参数传递给c ++ 2编译器会产生不同的结果

[英]Passing pointer as argument c++ 2 compilers different results

我今天正在和另一位计算机科学专业的学生一起工作,他说他的课程涵盖了指针。 他试图通过创建一个示例来理解指针,在该示例中他将指针作为函数的参数传递,并将该函数内引用的指针参数设置为等于三角形的斜边(三角形的另外两个侧面也是传递给函数作为双参数)。

当我向他解释指针的工作原理时,我指导了他应该怎么做,我们最终得到了类似下面的示例代码。 尽管我们付出了很多努力,他的编译器仍然无法编译,但是VS2013的编译器运行正常。

我的问题很简单:下面提供的代码对我们来说有什么问题吗? 我确实告诉过他,您可能会使用动态内存分配,而不是将指针设置为等于程序中定义的另一个变量的地址,但是似乎令我感到困惑的是为什么代码无法编译。 完全相同的代码,一个编译,另一个不编译。 我只想确保我提供的信息正确无误。

当然,这要感谢stackoverflow社区。

#include <iostream>
#include <cmath>

using namespace std;

void hypotenuse(double a, double b, double *ptr);

int main()
{
    //double *ptr = new double;
    double *ptr;
    double c;
    ptr = &c;

    hypotenuse(3, 4, ptr);

    cout << ptr << '\n' << *ptr;

    cin.get();
}

void hypotenuse(double a, double b, double *ptr)
{
    *ptr = sqrt(a*a + b*b);
}

编辑帖子是因为我们确实包含了cmath标头,在本示例中我只是忘了编写它,因为VS2013不需要它。 我很抱歉。

GCC和Visual C ++都符合此处的要求。 如果我们查看C ++标准草案,请参阅[res.on.headers]部分:

C ++标头可以包括其他C ++标头。 C ++标头应提供在其提要中出现的声明和定义。 提要中显示为包括其他C ++头的C ++头应提供出现在那些其他头的提要中的声明和定义。

Visual C ++在其标准库中的某个位置决定包含<cmath> 从现在开始,请遵循良好的做法,并始终包含您使用的函数的标头。

此问题中发布的代码无法按原样使用gcc进行编译,因为它缺少定义sqrt的数学标头的包含。 您的编译器错误/警告应明确显示此问题,请密切注意那些消息。

因为sqrt不是c ++语言的一部分,所以必须为cmath标头添加一个include。 在您的朋友代码的某些迭代中,您可能直接或间接包含了此标头,但是由于那里没有有关所使用的编译器的信息以及确切的错误消息(纯粹是推测),您需要将该信息包含在这样的问题中,以便得到更好的答案。 当包含cmath ,代码将编译并运行而不会出现问题

您的代码想要的结果是什么?

  1. 您正在计算斜边,然后
  2. 显示指针的地址ptrdouble c的内容。

可能的错误:

  1. 该函数内部的计算省略标题

解:

添加标题行: #include <cmath>

我即将结束这个问题。 我认为我将无法获得编译器错误消息,而这里真正要问的问题是我是否在代码中做了什么不应该做的错误。 在我看来,这个问题的答案是:“嗯,这取决于”,它取决于编译器。 但是我想编写当然是可移植的代码。

现在,我知道我犯了一些不良的编程习惯小错误,例如没有通过引用传递,忘记包括cmath的头文件,以及可能为未定义变量的地址分配了一个指针。可以设置返回类型,而不是传递指针参数,依此类推。 虽然,似乎我没有执行任何应引起编译器错误的操作,但是,嘿,我是谁,我知道什么?

我无法从编译该代码的学生那里收到错误消息,但是我相信他正在使用的IDE是Cloud 9,这是一种可在浏览器中运行的在线IDE。 我不知道它使用的是哪个版本的gcc或g ++,我去了网站,进行了注册,并能够很好地编译我的代码。 我可以向您保证,这是我使用的完全相同的代码,因为我从电子邮件中获取了该代码,他无法在自己的计算机上或在自己的云端9帐户上编译该代码。

因此,我认为这个问题的答案是,如果我可以这样说的话,我还没有做过任何违反C ++语言的事情。 无论如何,只是以为我还是要说声谢谢,对不起浪费人们的时间。

首先初始化没有值的指针( double* ptr; )是一种不好的做法,并且可能导致未定义的行为。

在大多数情况下,您不应声明void _ (T,T*)函数,而应将T*替换为返回值。 这使得返回值优化基本上可以内联函数调用。 它也更具可读性:

double hyp;
hypotenuse(3, 4, &hyp);

double hyp = hypotnuse(3, 4);

我了解您在教有关指针的知识,但是仍然可以做一个例子,使指针/引用有意义:

int /* error code */
getyx(int* y, int* x);

然后,您可以使用:

int y,x;
if(getyx(&y,&x)) {
    /* use value */
} else {
    /* error handling */
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM