函数就是子程序,是大型程序中某部分代码,有一个或多个语句块组成,负责完成某项任务,相对其他代码来说具备相对独立。函数最好定义在main函数前
C语言自己提供的函数,可在 cplusplus.com - The C++ Resources Network 或 cplusplus.com - The C++ Resources Network中查看
分类:IO函数 字符串操作函数 字符操作函数 内存操作函数 时间/日期函数 数学函数 其他函数
使用库函数需要引用对应头文件
如strcpy(string copy)的使用:
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[]="Sample string";
char str2[40];
char str3[40];
strcpy (str2,str1);
strcpy (str3,"copy successful");
printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);
return 0;
}
memset=memory set内存设置:(使用时需引用 <string.h> 头文件)
void * memset ( void * ptr, int value, size_t num );(ptr放地址,value是值,size_t是个大小、整型)
#include <stdio.h>
#include <string.h>
int main ()
{
char arr1[]="hello,world";
memset(arr1,'*',5); //arr1是目标,''中的是替代品,5是替换个数
printf("%s\n",arr1); //将hello替换成了*****
return 0;
}
自定义函数
函数组成
ret_type fun_name(para1,*)
{
statement; //语句项,交代函数的实现
}
//ret_type 返回类型
//fun_name 函数名
//para1 函数参数
两数相加函数:
int Add(int a, int b)
{
int c=0;
c=a+b;
return c;
}
两数求最大:
int MAX(int a, int b)
{
if (a>b)
return a;
else
return b;
}
将两个整型变量交换:
void Swap(int x,int y) //无返回值用void
{
int z=0;
z=x;
x=y;
y=z;
}
int main() //a和b传给x和y时(即实参传给形参),形参实际上是实参的临时拷贝
{ //形参和实参无实际联系,对形参的修改无法影响到实参
int a=10; //此代码无法达成目标
int b=20;
Swap(a,b);
printf("a=%d b=%d",a,b);
return 0;
}
void Swap(int* px,int* py) //无返回值时可用void
{
int z=0;
z=*px;
*px=*py; //不用指针无法达到数值交换的效果
*py=z; //此处是传的地址
}
int main()
{
int a=10;
int b=20;
Swap(&a,&b);
printf("a=%d b=%d",a,b);
return 0;
}
函数的参数
实际参数(实参):真实传给函数的参数(如:常量、变量、函数......),无论室参事何种类型的量, 在进行函数调用时,都必须有确定的值,以便把这些值传给形参
如:在上面正确代码中&a和&b就是实参
形式参数(形参):指函数名后面括号中的变量,形参在函数调用完成后就会被销毁,
只在函数中有效
如:在上面正确代码中px和py就是形参
函数的调用
传值调用:函数的实参和形参分别占不同内存块,对形参的修改不会影响到实参
int main()
{
int a=10;
int b=20;
int c=0;
c=Add(a,b); //Add(a,b); 就是传值调用
return 0;
}
传址调用:把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式
这种传参方式让函数内外变量建立起联系,即函数内部可直接操作函数外部的变量
int main()
{
int a=10;
int b=20;
Swap(&a,&b); //Swap(&a,&b); 就是传址调用
printf("a=%d b=%d",a,b);
return 0;
}
一些应用
打印100~200的素数:
#include <stdio.h>
int prime(int x) //是素数返回1,非素数返回0
{
int y=0;
for (y=2;y<x;y++) //优化:将y<x改成y<=sqrt(x),需用头文件<math.h>
{
if (x%y==0)
return 0;
}
return 1;
}
int main()
{
int i=0;
for (i=100;i<=200;i++)
{
if (prime(i)==1)
printf("%d ",i);
}
return 0;
}
判断闰年:
#include <stdio.h>
int leap_year(int x) //是闰年返回1,非闰年返回0
{
if ((x%4==0 && x%100!=0) || (x%400==0))
return 1;
else
return 0; //函数设计功能要尽量单一干净
}
int main()
{
int i=0;
scanf("%d",&i);
if (leap_year(i)==1)
printf("This is leap year\n");
else
printf("This is average year\n");
return 0;
}
实现整形有序数组二分查找:
#include <stdio.h>
int binary_search(int arr[],int k,int sz) //找到返回下标,没找到返回-1
{//数组传参过来实际传递的是数组首元素的地址,实际上这里的arr是指针,即不可再函数内计算sz大小
int left=0;
int right=sz-1;
while (left<=right)
{
int mid=(left+right)/2;
if (arr[mid]<k)
left=mid+1;
else if (arr[mid]>k)
right=mid-1;
else
return mid;
}
return -1;
}
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9,10};
int k=0;
scanf("%d",&k);
int sz=sizeof(arr)/sizeof(arr[0]);
int ret=binary_search(arr,k,sz);
if (ret==-1)
printf("Can't find");
else
printf("subscript is %d\n",ret);
return 0;
}
每调用一次此函数,num的值就会+1:
#include <stdio.h>
void None(int* a)
{
(*a)++; //++优先级较高,不加()会作用于a
}
int main()
{
int num=0;
None(&num);
printf("%d",num);
return 0;
}
函数的嵌套调用和链式访问
嵌套调用:
void A()
{
printf("Oh\n");
}
void B()
{
int i=0;
for ( i = 0; i < 3; i++) //B函数中调用A函数
A();
}
int main()
{
B();
return 0;
}
链式访问:把一个函数的返回值作为另一个函数的参数
int main()
{
printf("%d\n",strlen("abc")); //结果是3
printf("%d",printf("%d",printf("%d",43)));
//结果是4321,printf的返回值是打印字符的个数,打印顺序由内到外
return 0;
}
函数的声明和定义
函数声明:一般放在出现的函数的使用之前,函数声明一般放在头文件中
int Add(int,int); //函数定义在main函数后时或在另一个文件中时需声明
int mian()
{
int a=1;
int b=10;
int c=Add(a,b);
printf("%d",c);
return 0;
}
int Add(int a,int b)
{
int c=0;
c=a+b;
return c;
}
#include <stdio.h>
#include "Add.h" //引用自己设计的头文件时用引号
int main()
{
int a=1;
int b=10;
int c=Add(a,b);
printf("%d",c);
return 0;
}
函数的定义:指函数的具体实现,交代函数的功能实现
在Add.h文件中定义的函数:(可直接用 #include "Add.h" 声明)
int Add(int a,int b)
{
int c=0;
c=a+b;
return c;
}