单个文件中-函数的声明和定义:
#define _CRT_SECURE_NO_WARNINGS
//函数的调用必需满足先声明后使用--->这样子函数的定义可以写到后面编译器不会发出警告
//闰年的判断
//是闰年返回1
//不是闰年返回0
//函数声明
int is_leap_year(int y);
#include<stdio.h>
int main()
{
int y = 0;
scanf("%d", &y);
//判断是否是闰年
if (is_leap_year(y))
{
printf("%d是闰年\n",y);
}
else
{
printf("%d不是闰年\n",y);
}
return 0;
}
//函数定义
int is_leap_year(int y)
{
if (y % 400 == 0 || ((y % 4 == 0 )&& (y % 100 != 0)))
return 1;
else
return 0;
}
函数的调用必需满足先声明后使用--->这样子函数的定义可以写到后面编译器不会发出警告
函数的定义也是一种特殊的声明,所以可以把定义放前面,如下代码示例:
//函数定义
int is_leap_year(int y)
{
if (y % 400 == 0 || ((y % 4 == 0) && (y % 100 != 0)))
return 1;
else
return 0;
}
#include<stdio.h>
int main()
{
int y = 0;
scanf("%d", &y);
//判断是否是闰年
if (is_leap_year(y))
{
printf("%d是闰年\n", y);
}
else
{
printf("%d不是闰年\n", y);
}
return 0;
}
多个文件中-函数的声明和定义:
就是将一个程序拆成多个文件进行分别加工,就好比计算机的实现可以将加减乘除分别拆成4个模块进行分别编写---->可以用于隐藏代码的实现,会在后面出一起相关的文章.
函数 的 声明(#.... .h) 、 类型的声明 放在 头⽂件(.h)中.
库函数相关头文件: C 标准库头文件 - cppreference.com
函数的 实现 是放在 原⽂件(.c)⽂件中 。
如下:
Static和Extern:
作用域(scope):一个变量在哪里可以使用,哪里就是他的作用域.
1. 局部变量的作⽤域是变量所在的局部范围。大括号里面定义的变量
2. 全局变量 的作⽤域是整个⼯程。 大括号外面定义的变量
Extern:是用来声明外部符号的
生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的⼀个时间段。
1. 局部变量的⽣命周期是:进⼊作⽤域⽣命周期开始,出作⽤域⽣命周期结束。
2. 全局变量的⽣命周期是:整个程序的⽣命周期。
Static是 静态的 的意思,可以⽤来:
• 修饰局部变量
• 修饰全局变量
• 修饰函数
static修饰局部变量:
//代码1:
#include<stdio.h>
void test()
{
int a = 0;
a++;
printf("%d ", a);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;;
}
//代码2:
#include<stdio.h>
void test()
{
static int a = 0;//局部变量被static修饰时
a++;
printf("%d ", a);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;;
}
//代码3:
#include<stdio.h>
int a = 0;//a为全局变量时
void test()
{
a++;
printf("%d ", a);
}
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
test();
}
return 0;;
}
对比代码1和代码2的效果,理解static修饰局部变量的意义:
代码1的test函数中的局部变量i是每次进⼊test函数先创建变量(⽣命周期开始)并赋值为0,然后 ++,再打印,出函数的时候变量⽣命周期将要结束(释放内存)即a=1被摧毁。
代码2 ,我们从输出结果来看,i的值有累加的效果,其实test函数中的i创建好后,出函数的时候是 不会销毁的,重新进⼊函数也就不会重新创建变量,直接上次累积的数值继续计算。
结论: static修饰局部变量改变 了 变量的⽣命周期 ,⽣命周期改变的 本质是改变 了 变量的存储类型 ,本来⼀个 局部变量是存储在内存 的 栈区 的,但是被 static修饰后存储到了 静态区。存储在 静态区的变量和全局变量是 ⼀样的, ⽣命周期就和程序的⽣命周期⼀样了,只有 程序结束,变量才销毁,内存才回 收。但是作⽤域不变的。
使用场景:未来⼀个变量出了函数后,我们还想保留值,等下次进⼊函数继续使⽤,就可以使⽤static 修饰。
static修饰全局变量:
extern 是⽤来声明外部符号的,如果⼀个全局的符号在A⽂件中定义的,在B⽂件中想使⽤,就可以使 ⽤extern进⾏声明,然后使⽤。 如图所示:代码1正常,代码2在编译的时候会出现 连接性错误 。 全局变量是具有外部链接属性的 static修饰全局变量以后,外部连接属性变成了内部连接属性 其它.c文件再也无法使用,但是再它原来那个文件还是能作为全局变量继续使用. 使用场景:如果⼀个全局变量,只想在所在的源⽂件内部使⽤,不想被其他⽂件发现,就可以使⽤ static修饰。
static修饰函数:
代码1是能够正常运⾏的,但是代码2就出现了链接错误。 static 修饰函数和static修饰全局变量是⼀模⼀样的 ,⼀个函数在整个⼯程都可以使⽤,被static修饰后,只能在本⽂件内部使⽤,其他⽂件⽆法正常的链接使⽤了。 本质是因为 函数默认是具有外部链接属性, 使得函数在整个⼯程中只要适当的声 明就可以被使⽤。 但是被static修饰后变成了内部链接属性 ,使得函数 只能在⾃⼰所在源⽂件内部使 ⽤。 使用场景:⼀个函数只想在所在的源⽂件内部使⽤,不想被其他源⽂件使⽤,就可以使⽤static修饰。