在main之前调用的预定义函数

时间:2014-02-10 10:51:43

标签: c++ c

我不明白如何以及何时调用此预定义函数sqrt(),如果我定义自己的函数sqrt()它会显示编译错误,那么为什么呢?虽然两个代码都驻留在我的可执行文件的(TEXT)部分,但预定义函数调用仍然有效并且对用户定义函数的调用失败。

#include<stdio.h>

int x = sqrt(16); 

int main()
{

     printf(" x =  %d\n",x);
     return 0;
}

输出:

x = 4;

当我调用我定义的sqrt()函数时,我得到了跟随错误,但是当我使用预定义函数时,同样的错误没有出现

错误:初始化元素不是常量

6 个答案:

答案 0 :(得分:8)

如果您定义了自己的sqrt函数,它将与math.h中已定义的函数发生冲突,错误。

进行调用是因为在输入main之前初始化了全局变量(或者更确切地说是命名空间范围变量) - x的初始化。

答案 1 :(得分:5)

在C中,具有静态存储持续时间的变量的初始化程序(这意味着它在程序的整个生命周期中存在,例如 x )必须是常量表达式。对函数的调用不是常量表达式,并且您将得到编译器错误,例如(来自GCC)错误:初始化元素不是常量。该标准还说“实现可以接受其他形式的常量表达式”,因此允许编译器接受对库函数(如 sqrt )的调用作为常量表达式。编译器知道 sqrt 将执行什么操作,甚至可以在编译期间对其进行评估,并将函数调用替换为其结果。

C ++有不同的规则,在初始化 x 时,你可以调用函数,甚至是你自己的函数。

答案 2 :(得分:1)

Gcc编译器以程序方式编译源文件。

  

使用g ++或c ++编译器。代码将完美运行

我使用g ++编译器编译代码,编译成功。

#include<stdio.h>
int mysqrt(int n)
{
return(n);
}
int a=mysqrt(10);

int main()
{
printf("%d",a);
return(0);
}

请忽略mysqrt函数的内部逻辑。它仅用于测试目的。

据我所知,这是gcc编译器的一个问题。

该标准第6.6条第3款

  

常量表达式不应包含赋值,增量,   递减,函数调用或逗号运算符,除非它们是   包含在未评估的子表达式中。

常量表达式不得包含已计算的函数调用。

那是因为

  

可以在翻译期间评估常量表达式而不是   运行时,因此可以在常量可以使用的任何地方使用   是

gcc编译器能够通过在编译时执行库函数来计算常量表达式。但是它无法通过在编译时执行用户定义的函数来计算常量表达式。但是g ++和c ++编译器能够做这个工作。

答案 3 :(得分:0)

它说已经定义了一个名为sqrt()的函数(math.h有其声明)

当你添加math.h头文件时,它包含sqrt()函数的声明,该声明在库中,将在链接时添加。

当您尝试使用相同名称定义自己的函数时,编译器会对要调用的函数(您的函数或已在math.h中声明的函数)感到困惑。

将您的函数名称更改为my_sqrt(),在定义和调用时它应该可以正常工作。

注意:尝试了解编辑过程。在每个阶段会发生什么,你会更好地了解什么是幸福的。

答案 4 :(得分:0)

你得到的错误是由Luchian在上面解释的原因引起的。

准确地说明您的问题,您需要了解 Preprocessor Directives

  

预处理程序指令是程序代码中包含的行   前面有一个井号(#)。这些行不是程序语句   但预处理器的指令。预处理器检查了   在实际编译代码之前的代码开始并解析所有这些   任何代码实际生成之前的指令   语句。

您可以在输入main函数之前简单地定义x:

 #define x BLAH

我认为这会清除你的想法。 Cheerss!

答案 5 :(得分:0)

尝试在另一个文件中定义该函数,并在此处包含该文件。或者只是简单地在初始化之前声明函数