在C++中,为什么我不需要包含任何使用Sqt()函数的东西呢? 我只是学习C++。使用g++版本3.2.3、g++hworld.cpp编译: double sqrt(double); int main(){ double x = sqrt(1515.15); return 0; }

在C++中,为什么我不需要包含任何使用Sqt()函数的东西呢? 我只是学习C++。使用g++版本3.2.3、g++hworld.cpp编译: double sqrt(double); int main(){ double x = sqrt(1515.15); return 0; },c++,include,sqrt,cmath,C++,Include,Sqrt,Cmath,这可以很好地编译,但是如果我们用sqrtfoo替换sqrt,编译器会说sqrtfoo不能用作函数。我想我必须包括cmath,但我想不是吗?在包含任何内容之前,请有人解释一下我的程序可以访问哪些内容?作为比较,gcc不允许我这样做,说未定义对“sqrt”的引用。谢谢。您不需要包含cmath,因为您的代码在第一行已经有了sqrt的原型。您不需要包含cmath,因为您的代码在第一行已经有了sqrt的原型。头文件只包含声明签名,在第一行原型中包含了一个:double sqrtdouble 编译器编译得很

这可以很好地编译,但是如果我们用sqrtfoo替换sqrt,编译器会说sqrtfoo不能用作函数。我想我必须包括cmath,但我想不是吗?在包含任何内容之前,请有人解释一下我的程序可以访问哪些内容?作为比较,gcc不允许我这样做,说未定义对“sqrt”的引用。谢谢。

您不需要包含cmath,因为您的代码在第一行已经有了sqrt的原型。

您不需要包含cmath,因为您的代码在第一行已经有了sqrt的原型。

头文件只包含声明签名,在第一行原型中包含了一个:double sqrtdouble


编译器编译得很好,因为您已经声明在某个地方定义了这个函数。编译后发生的步骤负责实际查找该函数定义。这叫做链接,在这个阶段链接器查找这些定义。对于sqrtfoo,它找不到任何东西,而对于sqrt,它在一些标准库中找到它,我不知道这里的详细信息。

头文件只包含声明签名,您在第一行原型中包含了一个:double sqrtdouble


编译器编译得很好,因为您已经声明在某个地方定义了这个函数。编译后发生的步骤负责实际查找该函数定义。这叫做链接,在这个阶段链接器查找这些定义。对于sqrtfoo,它找不到任何东西,而对于sqrt,它在一些标准库中找到它,我不知道这里的详细信息。

正如现有答案所解释的,double sortdouble提供了一个原型,让编译器知道函数存在

但您也提到,在GCC下,这不起作用。当你构建C或C++程序时,源代码被编译成对象格式。然后将对象文件链接在一起,形成一个可执行文件

要看到这一点,请尝试

gcc -c hello.c
这告诉GCC编译-c源文件hello.c。假设hello.c存在并且没有错误,您将在当前目录中找到hello.o。现在试试

gcc -o hello hello.o
这告诉GCC将hello.o链接到适当的系统库,并生成一个名为hello的输出文件。如果hello.c使用数学函数,还需要在数学库中链接:

gcc -o hello hello.o -lm
-l用于告诉gcc在默认libc库之外包含额外的库。m指libm,它是包含sqrt的数学库。如果您的程序只使用一个源文件,通常会隐式要求GCC在单个命令中编译和链接:

gcc -o hello hello.c -lm
现在谈谈你的问题。GCC不会编译上述代码,因为您没有要求它在数学库中链接。但是g++可以接受它。存在非常严重的堆栈溢出。根据公认的答案,

C++运行时LIbSTDC++ +请求LBM,所以如果编译C++ 使用gccg++编程,您将自动获得libm链接


由于LISSTDC++是C++语言运行库,默认情况下是由G++组成的。由于依赖于libm,链接器会在生成最终二进制程序时自动加载libm。

正如现有答案所解释的,double-sortdouble提供了一个原型,让编译器知道函数存在

但您也提到,在GCC下,这不起作用。当你构建C或C++程序时,源代码被编译成对象格式。然后将对象文件链接在一起,形成一个可执行文件

要看到这一点,请尝试

gcc -c hello.c
这告诉GCC编译-c源文件hello.c。假设hello.c存在并且没有错误,您将在当前目录中找到hello.o。现在试试

gcc -o hello hello.o
这告诉GCC将hello.o链接到适当的系统库,并生成一个名为hello的输出文件。如果hello.c使用数学函数,还需要在数学库中链接:

gcc -o hello hello.o -lm
-l用于告诉gcc在默认libc库之外包含额外的库。m指libm,它是包含sqrt的数学库。如果您的程序只使用一个源文件,通常会隐式要求GCC在单个命令中编译和链接:

gcc -o hello hello.c -lm
现在谈谈你的问题。GCC不会编译上述代码,因为您没有要求它在数学库中链接。但是g++可以接受它。存在非常严重的堆栈溢出。根据公认的答案,

C++运行时LIbSTDC++ +请求LBM,所以如果编译C++ 使用gccg++编程,您将自动获得libm链接

由于LISSTDC++是C++语言运行库,默认情况下是由G++组成的。由于它取决于libm,链接器在生成最终二进制程序时会自动加载libm。

好的
,我认为include语句中发生的不仅仅是函数原型。我认为“include”实际上包含了一些我以前无法访问的额外代码,但显然它已经在那里的某个地方了,如果我声明它,它是可以访问的吗?我想知道为什么在使用gcc编译时,这种方法不起同样的作用?@user1676558:gcc的问题很可能是您没有链接到数学库。尝试将-lm添加到命令行中。好吧,我认为include语句中的内容不仅仅是函数原型。我认为“include”实际上包含了一些我以前无法访问的额外代码,但显然它已经在那里的某个地方了,如果我声明它,它是可以访问的吗?我想知道为什么在使用gcc编译时,这种方法不起同样的作用?@user1676558:gcc的问题很可能是您没有链接到数学库。请尝试将-lm添加到命令行。谢谢您的详细解释谢谢您的详细解释