四、函数的声明
4.1 概念
对已经定义的函数,进行说明
函数的声明可以声明多次
4.2 为什么要说明
有些情况下,如果不对函数进行声明,编译器在编译的时候,可能不认识这个函数,因为编译器在编译C程序的时候,从上往下编译的
4.3 声明的方法
什么时候需要声明
1)主调函数和被调函数在同一个.c文件中的时候
①被调函数在上,主调函数在下(这种情况下不需要声明)
②被调函数在下,主调函数在上(编译器从上往下编译,在main函数(主调函数),不认识函数,需要声明)
怎么声明?
①直接声明
将被调用的函数的第一行拷贝过去,后面加分号
②间接声明
将函数的声明放到头文件中,.c程序包含头文件即可
2)主调函数和被调函数不在同一个.c文件中的时候一定要声明
声明的方法:
直接声明法
将被调用的函数的第一行拷贝过去,后面加分号,前面加extern
间接声明法
将函数的声明放在头文件中,.c程序包含头文件即可
五、函数的调用
函数的调用方法
变量=函数名(实参列表);//带返回值的
函数名(实参列表);//不带返回值的
没有参数也没有返回值 直接写函数名,并且要在后面加括号
有参数,没有返回值 需要在函数名右边括号中传入参数,参数可以是常量表达式,也可以是变量表达式
有参数也有返回值 可以使用一个变量接受函数执行的结果(返回值),或者直接输入
#include <stdio.h>
void fun1()
{
printf("hello C++\n");
}
void fun2(int a,int b)
{
int sum;
sum=a+b;
printf("%d+%d=%d\n",a,b,sum);
}
void fun3(int a,int b)
{
int sum;
sum=a+b;
printf("sum=%d\n",sum);
return sum;
}
int main()
{
fun1();
fun2(1,2);
fun3(1,2);
return 0;
}
六、函数总结
定义函数的时候,关于函数的参数和返回值是什么情况,完全取决于函数的功能。当编写函数的时候,一开始不要想着函数如何传参和函数的返回值应该是什么而是当在编写代码的途中,要使用某些值,但是当前函数中不存在,此时就需要进行传参,这时候考虑怎么传参就是合适的时机
当函数编写完毕后,考虑是否要将某些结果返回给其他函数去使用,此时需要考虑返回值
七、变量的存储类型
7.1 内存的分区
1、内存:物理内存、虚拟内存
物理内存:实实在在存在的存储设备
虚拟内存:操作系统虚拟出来的内存。
操作系统会在物理内存和虚拟内存之间做映射。
在 32 位系统下,每个进程的寻址范围是 4G.0x00 00 00 00~0xff ff ff ff
在写应用程序的,咱们看到的都是虚拟地址。
在32位操作系统中,虚拟内存被分为两部分,3G的用户空间和1G的内核空间,其中用户空间是当前进程所私有的,内核空间,是一个系统中所有的进程所公有的
2、在运行程序的时候,操作系统会将 虚拟内存进行分区
1)堆
在动态申请内存的时候,在堆里开辟内存
2)栈
主要存放局部变量
3)静态全局区
1.未初始化的静态全局区
静态变量(定义变量的时候,前面加static修饰),或全局变量,没有初始化的,存在此区
2.初始化的静态全局区
全局变量、静态变量、赋过初值的、存放在此区
4)代码区
存放程序代码
5)文字常量区
存放常量的
7.2 普通的全局变量
概念:
在函数外部定义的变量
int num=100;//num,就是一个全局变量
int main()
{
return 0;
}
作用范围:
全局变量的作用范围,是程序的所有地方。
只不过用之前需要声明。声明方法 extern int num;
注意声明的时候,不要赋值。
生命周期:
程序运行的整个过程,一直存在,直到程序结束。
#include<stdio.h>
int num;
void fun()
{
num=666;
}
int main()
{
printf("num=%d\n",num);
fun();
printf("num=%d\n",num);
return 0;
}
7.3 静态全局变量
概念:
定义全局变量的时候,前面用 static 修饰
static intnum=100;//num 就是一个静态全局变量
int main()
{
return 0;
}
作用范围:
static 限定了静态全局变量的作用范围
只能在它定义的.c(源文件)中有效
生命周期:
在程序的整个运行过程中,一直存在。
注意:定义静态全局变量的时候,如果不赋初值,它的值默认为0
#include<stdio.h>
//不定义默认为0
static int num;
void fun()
{
num++;
}
int main()
{
printf("num=%d\n",num);
fun();
printf("num=%d\n",num);
return 0;
}
7.4 普通的局部变量
概念:
在函数内部定义的,或者复合语句中定义的变量
int main()
{
int num;//局部变量
{
int a;//局部变量
}
}
作用范围:
在函数中定义的变量,在函数中有效
在复合语句中定义的,在复合语句中有效,
生命周期:
在函数调用之前,局部变量不占用空间,调用函数的时候,才为局部变量开辟空间,函数结束了,局部变量就释放了。
#include<stdio.h>
int num;
void fun()
{
int num=1000;
num++;
printf("num=%d\n",num);
}
int main()
{
fun();
fun();
fun();
return 0;
}
7.5 静态的局部变量
概念:
定义局部变量的时候,前面加 static 修饰
作用范围:
在它定义的函数或复合语句中有效。
生命周期:
第一次调用函数的时候,开辟空间赋值,函数结束后,不释放,以后再调用函数的时候,就不再为其开辟空间,也不赋初值,用的是以前的那个变量。
#include<stdio.h>
int num;
// void fun()
// {
// int num=1000;
// num++;
// printf("num=%d\n",num);
// }
void fun1()
{
//静态局部变量不会随着当前函数执行结束而释放空间
static int a=60;
a++;
printf("a=%d\n",a);
}
int main()
{
// fun();
// fun();
// fun();
fun1();
fun1();
fun1();
return 0;
}
7.6 外部函数
定义的普通函数,都是外部函数
即函数可以在程序的任何一个文件中调用
在分文件编程中,只需要将函数的实现过程写在指定的.c文件中,然后将其声明写在指定的.h文件中,其他文件只要包含了头文件,就可以使用外部函数
7.7 内部函数
在定义函数的时候,返回值前面加static修饰,这样的函数被称为内部函数
static限定了函数的作用范围,在定义的.c中有效
内部函数和外部函数的区别:
外部函数,在所有地方都可以调用,
内部函数,只能在所定义的.c中的函数调用。
扩展:
在同一作用范围内,不允许变量重名。
作用范围不同的可以重名。
局部范围内,重名的全局变量不起作用。(就近原则)