C语言学习-函数(下)

C/C++
168
0
0
2024-04-11

单个文件中-函数的声明和定义:

#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修饰。