1.函数是什么
数学中的函数:f(x)=2*x+1
计算机中对函数的定义:
子程序,是一个大型程序的部分代码,由一个或多个语句块组成。它负责某项特定任务,具备象相对的独立性。(函数之间本身并无联系)比如strlen只是求字符串的长度,printf只是打印,add函数只是用来相加。
一般会有输入参数的返回值,提供对过程的分装和细节的隐藏。
2.c语言函数的函数分类
1.库函数
2.自定义函数
1.库函数
早期并没有库函数的概念
又因为经常要求字符串长度strlen、比较两个字符串大小strcmp、打印数据printf
又因为当时没有库函数所以每个人写自己的可能会出现冗余。
所以最后提供了库函数
库函数strcpy
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20]={0};
char arr2[]="hello bit";
strcpy(arr1,arr2);//strcpy(destation(copy到哪里),原代码)
printf("%s\n",arr1);
return 0;
}
memset
#include<stdio.h>
#include<string.h>
int main()
{
char arr[20]="hello bit";
memset(arr,'x',6);//memset(第0个,改变成,几个)
printf("%s\n",arr);
return 0;
}
自定义函数
由程序员自己创造的函数
返回类型 函数名(函数参数,函数参数)
{
函数体;
}
函数的作用相当于工厂:
写个函数求最大值
写个函数交换两值内容
、
并未交换原因:注意a b地址
注意x y地址
可得在这里创建新的变量单独的空间所以这里交换只改变了x y。并不影响a 和 b
正解:传地址
如果想改变外面的实参就用地址
实际参数(实参)
真实传值给参数的叫做实参
swap(&a,&b);这里的a和b就是实参
实参可以是常量、变量、表达式、函数
形式参数(形参)
函数名后括号中的变量,因为形式函数只有在函数被调用的过程中才实例化(分配内存单元),所以叫做形式参数,形式参数当被调用完之后就自动销毁。因此形式函数中只有在函数中有效。
void swap(int *a,int *b)
{
int c=0;
c=*a;
*a=*b;
*b=c;
}
不占用内存空间
当调用时传递了&a &b
这时x y才开始开辟空间
当出函数时 自动销毁
形参实例化相当于对实参的一份临时拷贝 对形参修改不改变实参
函数的调用
传值调用:
函数的形参和实参分别占有不同的内存块 对形参的修改不会影响实参
传址调用:
将地址传递,建立了实参和形参之间的联系,(在函数内部的操作会影响外面)对形参的修改可能会影响实参
写一个函数判断是不是素数:
#include<stdio.h>
int is_sushu(int x)
{
int i=0;
if(x<=2)
return 1;
else
{
for(i=2;i<x;i++)
{
if(x%i==0)
{
return 0;
break;//这里可以不要break因为return 0;作用强于break;直接返回结果了
}
}
}
}
int main()
{
int a=0;
scanf("%d",&a);
if(is_sushu(a))
{
printf("是素数");
}
else
printf("不是");
return 0;
}
100-200素数
#include<stdio.h>
int main()
{
int j=0;
for(int i=100;i<=200;i++)
{
int flag=1;
for(j=2;j<=i-1;j++)
{
if(i%j==0)
{
flag=0;
break;
}
}
if(flag==1)
{
printf("%d ",i);
}
}
return 0;
}
优化
#include<stdio.h>
#include<math.h>
int main()
{
int j=0;
for(int i=101;i<=200;i+=2)//偶数一定不是素数 所以i+=2只判断奇数
{
int flag=1;
for(j=2;j<=sqrt(i);j++)//开根 因为a、b中一定有一个小于开根的值
{
if(i%j==0)
{
flag=0;
break;
}
}
if(flag==1)
{
printf("%d ",i);
}
}
return 0;
}
判断是否是闰年
#include<stdio.h>
int is_year(int x)//是否是闰年
{
if(x%4==0&&x%100!=0||x%400==0)
return 1;
else
return 0;
}
int main()
{
int n=0;
scanf("%d",&n);
if(is_year(n))
printf("是闰年");
}
写一个函数实现一个整数的有序数组的二分查找
写函数时要先想好它怎么输出
数组传参时传递的是首元素的地址。
#include<stdio.h>
#include<string.h>
int binary_search(int x[],int n,int m)//这里x[]看起来是数组本质上是地址
{
int right=n-1;
int left=0;
int mid=0;
while(1)
{
mid=(right+left)/2;//为了防止溢出可以写成mid=left+(right-left)/2;
if(m>x[mid])
{
left=mid+1;
}
else if(m<x[mid])
{
right=mid-1;
}
else
{
return mid;
break;
}
}
return -1;
}
int main()
{
int a[]={1,2,3,4,5,6,7,8,9};
int sz=0;
int m=7;
sz=sizeof(a)/sizeof(a[0]);
int n=binary_search(a,sz,m);
if(n==-1)
printf("找不到\n");
else
printf("下标是:%d",n);
}
写一个函数,每次调用这个函数就会使num增加1
#include<stdio.h>
int add(int* n)
{
*n+=1;
return *n;
}
int main()
{
int num=0;
int n=add(&num);
printf("%d\n",n);
int n1=add(&num);
printf("%d\n",n1);
return 0;
}
函数的嵌套调用和链式访问
- 嵌套调用
函数可以嵌套调用但不能嵌套定义
2.链式访问
#include<stdio.h>
#include<string.h>
int main()
{
int n=strlen("abcdef");
printf("%d\n",n);
printf("%d\n",strlen("abcdef"));//链式访问 把一个函数的返回值作为另一个函数的参数
return 0;
}