调用函数前未声明会出现什么情况?

原创 2013年12月04日 16:44:04

查看关于c编程的书籍可以知道,在函数调用之前,要求先声明,这是为了告诉编译器函数返回值的类型,函数接受的参数的类型和个数。而如果函数在调用之前已经定义好了,即编译器知道函数的返回值类型,函数接受什么样的参数以及参数的个数。所以可以得知,告诉编译器有关函数的信息有2中办法:1先定义 2先声明

函数的声明如下(原型):

                         返回值  函数名 (形式参数类型 形式参数名……);

举个例子:     int fan(int * A, char B);如果没有形式参数,那么就写成void;形式参数是一个局部变量,作用域只存在定义他的函数内部,形式参数名字可以省略,其他函数也可以使用相同的形式参数名字,特别注意这个声明后面一个分号,而在函数定义的时候这个分号是用没有的,取而代之的是{

如此声明之后,在调用函数时,编译器就可以检查函数的调用,确保函数的类型,参数等信息没有错误。编译器会把类型不对的实参,返回值按照函数声明的要求转换过来。

问题来了:

如果我们之前没有声明函数就调用了一个函数,会发生什么情况?

#include <stdio.h>

int main(void)
{
	int c;

     c = sun();
	printf("%d",c);
	return 0;

}
int  sun()
{
	return 3;
}

结果是什么呢?结果是3,同时提醒warning C4013: “sun”未定义;假设外部返回 int。如果再改下一些代码

#include <stdio.h>

int main(void)
{
	float c;

      c = sun();
	printf("%f",c);
	return 0;

}
float  sun()
{
	return 3.14;
}

我们得到的结果是-1610612736;

我们返回的值是一个大小为3.14的float型,然后再把3.14赋给float型的c,那么打印出来的结果应该也是3.14

但是我们实际得到的

调试信息:

这是为什么呢?

这是因为在调用sun的时候,编译器不知道sun函数的类型,参数,所以编译器默认函数的返回值是1个整型值,本来3.14是以浮点数存储的,其二进制为01000000010010001111010111000011,于是把这个浮点数方式的存储的二进制当成整数来解读,所以值为-858993472,然后再因为c是float型,所以最后的结果是-858993472.000000(在%f下,默认保存小数点后6位)。所以最上面的代码输出正确完全是刚好碰上了。

所以如果我们在调用前声明,加入语句float  sun();输出结果是:

调试信息: warning C4305: “return”: 从“double”到“float”截断

结果是正确显示了,但是为什么会出现 warning C4305: “return”: 从“double”到“float”截断?

原因是:

return 3.14;
在c中,如果不指定数据类型,那么小数常量会被认为是 double 类型的,所以在3.14是double型的,根据float  sun()转换成float型,于是会提示从“double”到“float”截断




总结:返回值类型不是整型的函数,在调用前需要先声明!


函数定义与声明

对函数的“定义”和“声明”不是一回事。“定义”是指对函数功能的确立,包括指定函数名,函数值类型、形参类型、函数体等,它是一个完整的、独立的函数单位。而“声明” 的作用则是把函数的名字、函数类型以及形参...
  • haiyan0106
  • haiyan0106
  • 2008年10月09日 19:35
  • 12859

c++函数必须先声明在使用

c++函数必须先声明在使用,比如:#include using namespace std; //void A(); void A() //定义并声明了函数A { cout...
  • ychongx
  • ychongx
  • 2015年06月19日 04:22
  • 3413

万恶之源:C语言中的隐式函数声明

1 什么是C语言的隐式函数声明在C语言中,函数在调用前不一定非要声明。如果没有声明,那么编译器会自动按照一种隐式声明的规则,为调用函数的C代码产生汇编代码。下面是一个例子:int main(int a...
  • smstong
  • smstong
  • 2016年01月15日 14:49
  • 5630

用static声明的函数和变量小结

static 声明的变量在C语言中有两方面的特征:  1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。  2)、变量用st...
  • u010193457
  • u010193457
  • 2015年07月24日 15:54
  • 3876

两个线程同时调用一个函数会出现什么情况?

最近在研究多线程,然后突然想到如果两个线程同时访问一个函数的话,要不要加锁呢,加锁怎么加,不加又怎样这样的问题..然后去网上找了些帖子学习学习...... 上面的代码明显执行...
  • tt_man
  • tt_man
  • 2016年08月26日 10:12
  • 924

两个线程同时调用一个函数会出现什么情况?

两个线程同时调用一个函数会出现什么情况? 最近在研究多线程,然后突然想到如果两个线程同时访问一个函数的话,要不要加锁呢,加锁怎么加,不加又怎样这样的问题..然后去网上找了些帖子学习学...
  • a2274335673
  • a2274335673
  • 2016年08月31日 11:20
  • 8788

丁丁云网络验证delphi调用函数声明源码

  • 2015年08月19日 20:48
  • 3KB
  • 下载

什么情况下,类的析构函数应该声明为虚函数?

析构函数的用法:1.每个析构函数(不加 virtual) 只负责清除自己的成员。 2.可能有基类指针,指向的确是派生类成员的情况。 对于第二种情况: 正确执行:基类指针可以指向派生类的对象(多态性)...
  • firefly_2002
  • firefly_2002
  • 2012年10月25日 12:05
  • 2560

c++ 什么情况下需要将基类的析构函数声明为虚函数

原文链接:http://www.cnblogs.com/lixiaohui-ambition/archive/2012/07/13/2589716.html 1.为什么基类的析构函数是虚函数...
  • wjw7869
  • wjw7869
  • 2015年09月30日 16:10
  • 291

RTX:RTX系统调用函数分类、声明、功能及注意事项

【事件标志管理函数】 函数名              描述  os_evt_clr          清除至少一个事件标志。  os_evt_get          获取事件标志,使 os_evt...
  • sinat_36184075
  • sinat_36184075
  • 2017年04月22日 17:01
  • 385
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:调用函数前未声明会出现什么情况?
举报原因:
原因补充:

(最多只允许输入30个字)