C语言-函数
/函数的定义int MAX(int x, int y)//函数类型与返回值类型相同x : y);//三目运算符#define _CRT_SECURE_NO_WARNINGS//放在最上边才能识别int main()int a = 0;int b = 0;//函数的调用//scanf中""里是什么样的格式就输入成什么样的格式,但像这种"%d%d"两个整数要输入空格return 0;//错误写法voi
一、函数定义
子程序,负责完成某项特定任务,相较于其他代码,具备相对的独立性
二、函数的分类
1.库函数
2.自定义函数
2.1库函数
c语言本身提供的一种函数
常用:
IO函数:输入输出相关函数,头文件为<stdio.h>
字符串操作函数 : <string.h>
字符操作函数
内存操作函数
时间或日期函数
数学函数
其他库函数
以下两个例子都需要头文件<string.h>,但在VS2022比较智能,没有错误和警告
例1:strcpy 由名字联想->字符串拷贝
#include <stdio.h>
int main()
{
char arr1[20] = { 0 }; //char为字符型
char arr2[] = "hello bit"; //int arr2[] = { hello bit };字符串用""
strcpy(arr1, arr2);//前为destination,后为source
printf("%s", arr1);//字符串打印用%s
return 0;
}
例2:memset->内存设置
//将hello改为xxxxx
#include<stdio.h>
int main()
{
char arr[20] = "hello word";
memset(arr,'x',5);
printf("%s", arr);
return 0;
}
将wor改为yyy
#include<stdio.h>
int main()
{
char arr[20] = "hello world";//arr在h前 arr+1在e前
memset(arr+6, 'y', 3);//arr+6在w前
printf("%s\n", arr);
return 0;
}
如何学会使用库函数?:
http://en.cppreference.com
http://zn.cppreference.com
尽量使用英文版去看
2.2自定义函数
//函数的定义
int MAX(int x, int y)//函数类型与返回值类型相同
{
return(x > y ? x : y);//三目运算符
}
#define _CRT_SECURE_NO_WARNINGS//放在最上边才能识别
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
//函数的调用
scanf("%d%d", &a, &b);//scanf中""里是什么样的格式就输入成什么样的格式,但像这种"%d%d"两个整数要输入空格
int m = MAX(a, b);
printf("%d", m);
return 0;
}
//错误写法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void swap(int x, int y)//x,y叫形参
{
int z = 0; //x,y,z,a,b都有自己的地址,此函数只交换了x,y的地址,不影响a和b
z = x;
x = y;
y = z;
}
//给面试官的解释
//当时实参传递给形参时,形参是实参的一份临时拷贝,此时形参占独立的内存
//对形参的修改不会影响实参
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);//a和b是实参
printf("交换前:a=%d,b=%d\n",a,b);
swap(a,b);
printf("交换后:a=%d,b=%d\n", a, b);
return 0;
}
//正确写法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void swap(int *px, int *py)
{
int z = *px;//a与b的值交换了,地址没变
*px = *py;//不加*只是交换了地址,加*让地址相应的值交换
*py = z;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d%d", &a, &b);
printf("交换前:a=%d,b=%d\n", a, b);
swap(&a, &b);
printf("交换后:a=%d,b=%d\n", a, b);
return 0;
}
三、函数的参数
3.1实际参数
真实传给函数的参数,叫实参
实参可以是:常量,变量,表达式,函数等
例如
int Add(int x, int y)
{
int z = 0;
z = x + y;
return 0;
}int c=Add(a+3,b);
int c=Add(Add(a,3),b);//无论实参适合种类型的量,在进行函数调用时,它们都有确定的值,以便把这些值传给形参
3.2形式参数
指函数名后括号里的变量,因为形参只有在函数被调用的过程中才实例化
当函数调用完成之后就自动销毁了,与局部变量类似
四、函数的调用
void swap1(int x, int y)
{
int z = 0;
z = x;
x = y;
y = z;
}
void swap2(int *px, int *py)
{
int z = 0;
z = *px;
*px = *py;
*py = *z;
}
传值调用:
swap1(a, b);
函数的形参和实参分别占有不同的内存块,对形参的修改不会影响实参
传址调用:
真正建立联系,函数内部可以直接操作函数外部的变量
swap2(&a, &b);
五、函数的嵌套调用和链式访问
5.1嵌套调用
5.2链式访问前提条件:(函数必须有返回值)
#include<stdio.h>
#include<string.h>
int main()
{
int len = 0;
len=strlen("abcdef");
printf("%d\n", len);
printf("%d\n", strlen("abcdef")); /*链式访问*//*把一个函数的返回值变成另一个函数的参数*/
//需要注意strlen的返回值类型
printf("%d", printf("%d", printf("%d", 43)));//printf的返回值是打印字符的个数
return 0;
}
扩展:
int mian(void) //明确表明main中无参数,本质上main是有参数的
{
return 0;
}
int main(int argc,char*argv[],char*envp[])
{
return 0;
}
六、函数的声明和定义
6.1函数声明
一般放在头文件 源文件加上#include"add.h" 本质上将文件add.h的内容拷贝过来
函数定义在main函数后,会警告
解决方法:需要函数的声明,在main函数前些上 add(int x, int y);
6.2函数定义
七、函数递归
7.1什么是函数的递归
自己调自己
把大事化小
7.2递归的俩个必要条件
存在限制条件,当满足时递归将不再继续
每次递归调用是越来越接近这个条件
7.3递归与迭代
求n的阶乘(递归)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int fac(int n)//错误一:未标明类型
{
if (n == 1)//错误二:写为n=1
{
return 1;
}
else
{
return n * fac(n - 1);
}
}
int main()
{
int n=0;
int ret = 0;
scanf("%d", &n);
ret=fac(n);
printf("%d", ret);
return 0;
}
求n的阶乘(迭代---非递归)
int fac(int n)
{
int ret = 1;
int i = 0;
for (i = 1; i <= n; i++)
{
ret*=i;
}
return ret;
}
int main()
{
int n=0;
int ret = 0;
scanf("%d", &n);
ret=fac(n);
printf("%d", ret);
return 0;
}
求第n个斐波那契数列(递归)
int Fib(int n)
{
if (n <= 2)
return 1;
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
int n = 0;
int ret = 0;
scanf("%d", &n);
ret = Fib(n);
printf("%d", ret);
return 0;
}
使用递归有时效率低下,重复率高,此时可以选择函数的迭代
更多推荐

所有评论(0)