6.C语言函数

本文详细介绍了C语言中的函数概念,包括库函数的使用、自定义函数的定义、实参与形参的关系、return语句的应用、嵌套函数调用、链式访问以及函数声明与定义的规则,特别关注了static和extern关键字的作用。
摘要由CSDN通过智能技术生成

1.C语言中的函数是什么

函数可以理解为子程序。C语言则是由无数小的函数组合而成。常见的有库函数和自定义函数。

2.库函数

直接点讲,我们要实现某种功能时,只要使用这些函数就可以了,而这些函数是编译厂在基于标准库(ASCII提供的C语言标准)下给出的函数,就叫库函数,根据功能的不同,把库函数放在不同的头文件,进行声明。
头文件大全:https://zh.cppreference.com/w/c/header
https://legacy.cplusplus.com/reference/clibrary/
来一个使用示例:

#include<stdio.h>
#include<math.h>
int main()
{
   double num=49.0;
   double res=sqrt(num);
   printf("%lf\n",res); 
   return 0;
}

在这里插入图片描述

3.自定义函数

顾名思义:自定义
语法:

ret_type fun_name(形式参数)
{

}

ret_type:函数返回类型,例如void(什么都不返回),int
fun_name:函数名
如果知道参数类型 int 和参数名字,则函数返回类型是int
如果知道参数是void,即无参数,则函数返回类型是void
例子
写一个调用减法函数

#include<stdio.h>
int Sub(int x,int y)
{
   int sub=0;
   sub=x-y;
   return sub;
}
int main()
{
   int a=0;
   int b=0;
   scanf("%d %d",&a,&b);
   int c = Sub(a,b);
   printf("%d\n",c);
   return 0;
}

4.实参与形参

4.1实参

顾名思义:实际传给函数的参数。
如上面实现调用减法函数中,int c=Sub(a,b)调用Sub函数时,a,b就是实际参数。

4.2形参

只有调用函数时,才有它的价值,其他时间时,它是一个虚无的东西,不会向内存申请空间。
函数被调用时,为了存放实参的值,形参才会向内存申请空间。

4.3实参与形参关系

在这里插入图片描述

形参x,y得到实参a,b的值,但是,x和y地址与a和b的地址不一样。所以,形参是实参的一个临时copy。

5.return

用法:
1.return 返回数值,若值的数据类型和函数返回类型不一样,系统会自动将值转换成函数返回类型。
2.return返回表达式,实质返回表达式的值。
3.return没有返回什么,适合void函数类型
3.return执行,彻底返回,后边代码不执行

注意的是
数组传参,形参是不会创建新的数组。

6.嵌套使用和链式访问

6.1嵌套使用

  函数之间互相调用

例子:计算某年某月某日在某年是第多少天。
调用两个函数:判断闰年平年函数;计算天数函数

#include<stdio.h>
int is_leap_year(int year)
{
	if ((year % 4 == 0 && year % 100 != 0) && (year % 400 != 0))
		return 1;
	else
		return 0;
}


int GetDaysOfYear(int year,int y,int z)
{
	int i = 0;
	int days = 0;
	int arr[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
	if (is_leap_year(year))
	{
			arr[1] = 29;
		
	}
	
	for ( i=0; i <y-1 ; i++)
		{
		    days+=arr[i];
		}
	days +=z;
	
	return days;
}
int main()
{
	int year = 0;
	int month = 0;
	int day = 0;
	printf("请输入你想知道的年月日:\n");
	scanf("%d %d %d",&year,&month,&day);
	
	int DAYS = GetDaysOfYear(year, month, day);
	printf("该日期是%d年的%d天",year,DAYS);
	return 0;
}

在这里插入图片描述

6.2链式访问

将⼀个函数的返回值作为另外⼀个函数的参数
例子1:
把strlen的返回值直接作为printf函数的参数

#include<stdio.h>
int main()
{
  printf("%d\n",strlen("abcdef"));
  return 0;
}

例子2:猜猜打印出什么

#include<stdio.h>
int main()
{
	printf("%d\n", printf("%d",43));
	return 0;
}

答案是:432
printf函数返回的是打印在屏幕上的字符的个数
第二个printf打印43,屏幕有2个字符,则返回2
第一个printf打印2,屏幕有1个字符,则返回1
但是前面没有printf了,所以屏幕不会打印1

7函数声明和定义

7.1代码放在单个文件中

函数调用,要先声明后使用(定义),函数的定义也是特殊的声明。
假如我们反其道而行,先调用,后使用,无声明。
我们用上面5.1的代码做实验,将 GetDaysOfYear函数和is_leap_year函数放在main函数后面,is_leap_yea函数放在GetDaysOfYear函数后面。则出现了下面警告。
在这里插入图片描述
我们在上面不变的情况下,在main函数前面对调用函数进行声明。

#include<stdio.h>

int GetDaysOfYear(int year, int y, int z);
int is_leap_year(int year);

int main()
{
	int year = 0;
	int month = 0;
	int day = 0;
	printf("请输入你想知道的年月日:\n");
	scanf("%d %d %d", &year, &month, &day);

	int DAYS = GetDaysOfYear(year, month, day);
	printf("该日期是%d年的%d天", year, DAYS);
	return 0;
}

int GetDaysOfYear(int year, int y, int z)
{
	int i = 0;
	int days = 0;
	int arr[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
	if (is_leap_year(year))
	{
		arr[1] = 29;

	}

	for (i = 0; i < y - 1; i++)
	{
		days += arr[i];
	}
	days += z;

	return days;
}

int is_leap_year(int year)
{
	if ((year % 4 == 0 && year % 100 != 0) && (year % 400 != 0))
		return 1;
	else
		return 0;
}

这是一种先声明后使用的用法,第二种用法,是定义直接在调用函数之前完成,因为定义也是一种特殊的声明,那么这种方法就是我在5.1用的方法。

7.2代码放在多个文件中

上面是将所有代码放在一个文件里面,事实上,我们在企业中,会根据程序的功能,将代码放在不同文件中
一般,函数声明和类型的声明放在头文件(.h)中,函数的实现放在(.c)文件中。
例子:我们想要实现简单的减法计算功能
sub.h(函数声明):
在这里插入图片描述

sub.c(函数定义):
在这里插入图片描述

test.c(函数调用):
在这里插入图片描述

7.3关键字static和extern

static:
静态。
修饰局部变量、全局变量和函数。
extern:
声明外部符号。

static修饰局部变量
在这里插入图片描述
在这里插入图片描述
现象:test函数中的i创建并使用后,并不会销毁,main函数循环,再进入test函数时,不会给i重新初始化为0,而是用上次最后的 i 数值进行计算。
结论:static修饰局部变量,改变了局部变量的生命周期,实质改变局部变量的存储类型。局部变量实质存储在内存栈区,被static修饰后,存储到静态区。静态区的变量和全局变量的生命周期一样,只有程序结束,变量才销毁,但是static修饰的局部变量的作用域还是所在的局部范围。
在这里插入图片描述
知识点:
局部变量作用域:变量所在局部范围
全局变量作用域:整个工程
局部变量生命周期:进入作用域生命周期开始,出去作用域生命周期结束。
全局变量生命周期:整个程序的生命周期。

static修饰全局变量
sub.c

static int year = 2023;

test.c

#include<stdio.h>

extern int year;

int main()
{
	printf("%d\n",year);
	return 0;
}

extern声明外部符号
补充:一个全局符号再a文件定义,想要在b文件使用,就在b文件用extern声明,后使用。
现象:
出现debug,链接性错误。
结论:
全局变量被static修饰后,外部链接属性变为内部链接属性,只能在自己的源文件中使用,在其他源文件,即使声明了,也无法使用。

static修饰函数
sub.c

static int sub(int x, int y)
{
	return x - y;
}

test.c

#include<stdio.h>

extern int sub(int x,int y);

int main()
{
	printf("%d\n",sub(40,20));
	return 0;
}

现象: 出现了链接错误
结论:函数默认具有外部链接属性,函数在整个工程有适当声明则可以使用,被static修饰后,变成内部链接属性,只能在自己的源文件使用。
那什么时候可以使用static呢:
只想在自己的源文件中使用,不想其他文件使用时。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值