二二、函数(五)
二二、函数(五)1、static和inline
1)静态变量
利用static可以声明一个静态变量,static变量如果没有指定初始化的值,那么会初始化为0,无论有没有指定初始值,都只会初始化一次,静态变量的值不会因函数大括号结束而消失。语法如下
//static语法
static 类型 变量名称;
//示例
static int a;//count变量在函数Add()第一次调用的时候会初始化为0,当第二次Add()调用时,则不再初始化count变量
int Add(int a,int b)
{
static int count; //第二次Add()调用时,则count为1
count++;
。。。
}2)内联函数
可以使用inline声明一个内联函数,内联函数将会建议编译器把这个函数处理成内联代码以提升性能,但始终是建议,具体编译器是否采纳,由编译器决定。
//声明一个内联函数
inline int Add(int a,int b)
{
return a+b;
}2、从编译器的角度理解定义和声明
1)编译器编译代码的顺序
计算机并不能看懂C/C++语言,计算机的世界里只有二进制,因此,我们每一次编程,每一句代码,编译器都会编译成计算机能够读懂的二进制代码(机器语言),我们的代码是一篇写满了命令的文章,而编译器则是一个合格的翻译官,负责把我们的文章翻译给计算机听,计算机是一个合格的士兵,它从不质疑你的命令,你让它做什么它就做什么,就算你的命令是错的!
而编译器这个翻译官在读我们的文章的时候,它是从第一行,第一个字开始读的。因此可以先对函数声明,再对函数进行定义。
#include <iostream>
int main()
{
ave(1, 2);
}
int ave(int a, int b)
{ //大括号中的内容为函数的定义
return (a + b) / 2;
}2)函数的声明
以上的代码没有任何语法错误,但是不能编译,因为编译器读取到函数ave()的时候,它并不知道ave是什么,编译器即不知道ave需要什么样参数,也不知道ave函数返回什么样的值,因为ave不是C/C++编译器提供的函数!对于编译器来说,它此时不需要知道ave具体是什么功能,但是它需要知道ave函数返回的是什么类型的值,需要什么样的参数!
因此在一个函数使用之前,至少应该告诉编译器这个函数的基本信息,那就是这个函数的参数和返回值,这种告诉,就叫做函数的声明,就拿本例来说,函数的声明为int ave(int a,int b);
对于编译器来说,它此时并不需要知道参数的名字,只需要知道这个函数返回的是int类型的值,要求的是两个int类型的参数,因此声明也可以写为这样int ave(int,int);
综上所述,声明是人和编译器的事,声明并不需要翻译成计算机语言告诉计算机。但是函数的定义和计算机有关
//函数的声明
#include <iostream>
int ave(int a, int b); //函数的声明
int ave(int,int); //声明时,可以只说明参数类型即可,也可以多次声明
int main()
{
ave(1, 2);
}
int ave(int a, int b)
{ //大括号中的内容为函数的定义,函数的定义只能有一次
return (a + b) / 2;
}3)函数的定义和声明
不管我们和编译器谈的如何愉快,你给定的什么样子的函数声明,但是最终,还是要通过编译器告诉计算机这个函数的具体实现过程,这个实现过程的告诉,就是函数的定义。
函数的声明可以有多次,但是函数的定义只能有一次。
4)深入理解函数的定义和声明
声明的本质是与编译器的对话,单纯的声明并不存在内存的分配,只是给编译器一个大体的感念,既然是对话,我们可以多次对话,所以对于同一个事物,我们可以多次声明。
而定义的本质是通过编译器与计算机的对话,这就涉及到内存的分配和访问,因此同一个事物,不管声明多少次,但是只能有一次定义。
变量同样适用这个规则,我们可以通过关键字extern声明一个变量,而把这个变量的声明和定义分开。
写函数的声明的时候,没有写extern关键字,是因为函数的声明本事就是extern的,因此不需要手动指出。
extern的作用也是告诉编译器,此处只是一个声明,你去别处找定义,因此extern是针对的全局变量,因为局部变量不存在去别处找定义的可能性。而函数的声明自带extern属性,因此函数本身也是全局的。
#include extern int all; //声明一个变量int main(){ std::cout
页:
[1]