维基百科对函数的定义:子程序
在计算机科学中,子程序是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而相较于其他代码,具备相对的独立性。
一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。
//例如:两数相加
int Add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 10;
int b = 20;
int sum=Add(a, b);
printf("%d\n", sum);
}
1、库函数(C语言本身提供的函数)
2、自定义函数
(1)怎样学习库函数?
www.cplusplus.com
MSDN
https://en.cppreference.com/w/
(2)C语言常用的库函数
IO函数、字符串操作函数、内存操作函数、时间\日期函数、数学函数、其他库函数
注意:使用库函数,必须包含掌握库函数的使用方法。
//strcpy example
#include
#include
int main()
{
//strlen -string length 字符串求长度
//strcpy -string copy 字符串拷贝
char arr1[] = "bit";
char arr2[] = "#######";
strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
/* memset函数*/
//memory -内存 set -设置
//memset
//void * memset(void * ptr,int value,size_t num);
//把ptr所指向的空间的前num个字节内容,设置成指定的value的值
int main()
{
char arr[] = "hello world";
//将arr[]中前五个字符设置成*
memset(arr, '*', 5);
printf("%s\n", arr);
return 0;
}
输出结果:***** world
自定义函数和库函数一样,有函数名,返回值和函数参数。但是需要设计
//函数的基本组成
ret_type fun_name(para1,*)
{
statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1 函数参数
//定义函数
get_max(int x, int y)
{
if (x > y)
return x;
else
return y;
}
int main()
{
int a = 10;
int b = 20;
//函数的使用
int max = get_max(a, b);
printf("max=%d\n", max);
return 0;
}
//写一个函数交换两个变量的内容
//swap1不能完成任务
void Swap1(int x,inty)
{
int tmp=0;
tmp=x;
x=y;
y=tmp;
}
void Swap2(int *pa, int *pb) //void -没有返回值
{
int tmp = 0;
tmp = *pa;
*pa = *pb;
*pb = tmp;
}
int main()
{
int a = 10;
int b = 20;
printf("a=%d b=%d\n", a, b);
swap1(a,b);
Swap2(&a,&b);
printf("a=%d b=%d\n", a, b);
return 0;
}
输出结果:
a=10 b=20
a=20 b=10
为什么swap1不能完成任务? 当实参传给形参的时候,形参其实是实参的一份临时拷贝,对形参的修改是不会改变实参的,所以swap1不会完成。而swap是传的地址。
实际参数(实参):
真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。无论实参是和种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。例如main函数中传给swap函数的&numq,&num2是实际参数
形式参数(形参):
形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才分配内存单元,所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。例如:上面的swap中的Swap(int *pa, int *pb)是形参。
传值调用:
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。例如上面的swap1是传值调用。
传址调用:
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。例如:swap2。
#include
int is_prime(int n)
{
//是素数返回1,不是素数返回0
int j = 0;
for (j = 2; j < n; j++)
//优化for(j=2;j<=sqrt(n);j++)
{
if (n%j == 0) //找到了一个j整除n 所以不是素数
{
return 0;
}
//j
return 1;
}
int main()
{
int i = 0;
for (i = 100; i <= 200; i++)
{
//判断i是否为素数
if (is_prime(i) == 1)
printf("%d ", i);
}
return 0;
}
int is_leap_year(int y)
{
if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
return 1;
else
return 0;
}
int main()
{
int year = 0;
for (year = 1000; year <= 2000; year++)
{
//判断year是否为闰年
if (1 == is_leap_year(year))
{
printf("%d\n", year);
}
}
return 0;
}
//二分查找 在一个有序数组中查找具体的某个数
int binary_search(int arr[], int k,int 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 = 7;
//如果找到了返回这个数的下标,找不到则返回-1
int sz = sizeof(arr) / sizeof(arr[0]);
int ret = binary_search(arr,k,sz); //接受它的返回值
if (ret == -1)
{
printf("找不到指定的数字\n");
}
else
{
printf("找到了,下标是:%d\n", ret);
}
return 0;
}
输出结果:找到了,下标是:6
void Add(int *p)
{
(*p)++; //++的优先级比较高
}
int main()
{
int num = 0;
Add(&num);
printf("num=%d\n", num); //1
Add(&num);
printf("num=%d\n", num);//2
Add(&num);
printf("num=%d\n", num);//3
return 0;
}
嵌套调用:
函数和函数之间可以有机的组合的
链式访问:
把一个函数的返回值作为另外一个函数的参数
int main()
{
int len=0;
//第一种写法
len=strlen("abc");
printf("%d\n",len);
//第二种写法
printf("%d\n",strlen("abc"));
return 0;
}
int main()
{
printf("%d", printf("%d", printf("%d", 43))); //printf打印的是字符的个数 先打印43 再一次打印2 再一次1
return 0;
}
输出结果:4321
函数声明:
1、告诉编译器有一个函数叫什么、参数是什么、返回类型是什么。
2、函数的声明一般出现在函数的使用之前。要满足先声明后使用。
3、函数的声明一般要放在头文件中。
函数的定义:
函数的定义是指函数的具体实现,交代函数的功能实现。
**//函数声明**
int main()
{
int a=10;
int b=20;
int sum=0;
//函数调用
sum=Add(a,b);
printf("%d\n",sum);
return 0;
}
//函数的定义
int Add(int x,int y)
{
int z=x+y;
return z;
}