那些关于函数我们容易忽略的基础知识
相信在学校同学们看谭老师的教材的时候已经对函数有了“初步的认识”。
但是,如果你没有理解下面这几个例子,那并不能说你对函数入门了。
1.为什么要声明函数?
#include<stdio.h> |
上面代码void swap();
就是swap函数的声明
把对swap的声明写在main函数的上面是因为:
C的编译器从main函数的第一行开始,自上而下的分析你的代码。
在看到swap(a, b)
时,它需要知道swap()
的样子
也就是swap()的返回类型,参数类型,参数个数
这样它才能检查你对swap()的调用是否正确
接下来我们讨论,如果编译器不知道函数的返回类型,参数类型,参数个数的话,编译能否继续进行?
下面我们看两个例子,分析编译器能否正确执行我们的代码
#include<stdio.h> |
#include<stdio.h> |
第二种情况会报错:
“swap”未定义,假设外部返回int
“swap”重定义,不同的基类型
在没有对函数进行声明的情况下
旧标准会假设你所调用的函数所有的参数和返回类型都是int类型。
如果不是,就会发生上述的问题
2.定义函数的方式
请观察下面三种函数声明,这三种写法哪些是正确的?
//写法1: |
答案是,这三种写法都是可以的。
事实上,编译器看的是第三种写法。而我们常用的第一种写法是为了让我们自己和别人更好的理解我们写的代码,这是良好的写代码习惯。
然而还有这样一种声明方式,大家想一下,编译器可以识别吗?
void swap(); |
答案是可以的。
这种写法可以说是这几种写法中最方便的写法,那么这种写法是不是无懈可击的呢?
如果我改变了临时变量a,b的类型再试试呢?
#include<stdio.h> |
这回,输出的x,y就不我们所期望的了。为什么会这样?我在这里给出简单解释:
main函数
执行到调用swap函数的地方的时候,由于我们在声明swap函数
的时候并没有指定参数的类型,所以程序会猜测这两个变量的类型为int
类型。而在函数定义的时候类型却为double
,所以程序就有点“疑惑”了。
所以,这种类型的写法是错误的!
3.了解概念:块(block)
简单的来说,一个大括号{ }
就是一个块
4.作用域和生存期的关系
如果变量在作用域内,那么它的生存期一定存在
如果变量的生存期还没结束,它不一定在作用域内
5.没有参数时
当一个函数没有参数,应如何表示呢?
void f(void)
还是void f()
?
void f(void)
表示函数没有参数
void f()
表示参数未知
6.函数括号内的逗号与逗号运算符
我们思考一下,f(a,b)
会不会引发歧义?
如果有人认为这个逗号表示的是逗号运算符怎么办?
f(a,b)
表示函数f有a,b两个参数
f((a,b))
这个逗号才是逗号运算符,表示函数f只有一个参数b
7.函数内是否可以定义函数
C语言不允许函数内嵌套定义
8.return(i)
这样写会引起歧义,它的意思究竟是返回i还是调用return函数?
9.关于main函数
- main函数也是函数,是被其函数调用的
- main函数返回值是有意义的
int main()
还是int main(void)
?