将指针作为参数传递c ++ 2编译不同的结果

时间:2015-09-08 20:20:51

标签: c++ pointers

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

当我向他解释指针是如何工作的时候,我指导他应该做什么,最后我得到了类似下面的示例代码。尽管我们的努力,他的编译器仍然无法编译,但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);
}

Post被编辑是因为我们确实包含了cmath标题,我只是忘了在这个例子中写它,因为VS2013不需要它。道歉。

5 个答案:

答案 0 :(得分:2)

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

  

C ++标头可能包含其他C ++标头。一个C ++头应该提供   其概要中出现的声明和定义。一个C ++   在其概要中显示的标题包括其他C ++标题   提供概要中出现的声明和定义   那些其他标题。

在标准库的某处,Visual C ++决定包含<cmath>。从现在开始,遵循良好做法并始终包含您使用的功能的标题。

答案 1 :(得分:0)

此问题will not compile with gcc中发布的代码是因为它缺少定义sqrt的数学标头的包含。您的编译器错误/警告应该清楚地显示此问题,密切关注这些消息。

由于sqrt不是c ++语言的一部分,因此您必须为cmath标头添加一个包含。 可能在您的朋友代码的某些迭代中,您直接或间接地包含此标头但是没有关于在那里使用的编译器的信息以及确切的错误消息这纯粹是推测,您需要包括在这样的问题中的信息,以获得更好的答案。当您添加cmath时,代码将compile and run without issue

答案 2 :(得分:0)

您的代码的结果是什么?

  1. 您正在计算斜边,然后
  2. 显示指针的地址ptrdouble c的内容。
  3. 不可能的错误:

    1. 函数
    2. 中计算的省略标题

      解决方案:

      在标题栏中添加标题:#include <cmath>

答案 3 :(得分:0)

我非常接近关闭这个问题。我不认为我能够得到编译器错误消息,而这里真正被问到的问题是我在代码中做了什么错误,我不应该这样做。在我看来,这个问题的答案是,&#34;嗯,这取决于,&#34;这取决于编译器;但我想编写的代码当然是可移植的。

现在,我知道我已经做了一些错误编程实践的小错误,例如没有通过引用传递,忘记包含cmath的头,并且可能指定一个指向未定义变量的地址的指针。 ...我可以创建一个返回类型,而不是传递指针参数等等。虽然,我似乎没有做过应该调用编译器错误的任何事情,但是嘿,我是谁,我知道什么?

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

所以我认为这个问题的答案是我没有做过任何会违反C ++语言的事情,如果我能这样做的话。 无论如何,只是觉得我还是要表示感谢,并且抱歉浪费了人们的时间。

答案 4 :(得分:-2)

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

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

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

VS

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 */
}