目录
函数是什么
函数是C程序的构建块。每个函数本质上是一个自带声明和语句的小程序。可以利用函数把程序划分成小块,这样便于人们理解和修改程序。由于不必重复编写要多次使用的代码,函数可以使程序不那么单调乏味。此外,函数可以复用:一个函数最初可能是某个程序的一部分,但可以将其用于其他程序。
在计算机科学中,子程序,是一个大型程中的某部分代码,有一个或多个程序块组成。它负责完成某项特定任务,而且较于其他代码,具备相对独立性。
一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常集成为软件库。
C语言中的函数分为库函数和自定义函数
库函数
c语言自带的函数。需要使用时,需要引用头文件#include <>。使用MSDN进行查询
自定义函数
返回类型 函数名 (函数参数)
{ 语句项 }
1、利用自定义函数写出两个数的最大值
#include <stdio.h>
int MAX(int x, int y)
{
return (x > y ? x : y);
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("%d", MAX(a, b));
return 0;
}
2、写一个函数可以交换两个变量
#include <stdio.h>
void swap(int* a, int* b)
{
int tem = 0;
tem = *a;
*a = *b;
*b = tem;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("a = %d b = %d", a, b);
swap(&a, &b);
printf("\na = %d b = %d", a, b);
return 0;
}
3、计算两个数的平均数
#include <stdio.h>
double average(double a, double b)
{
return (a + b) / 2;
}
int main()
{
double x = 0;
double y = 0;
scanf("%lf %lf", &x, &y);//读取一个double类型用%lf
printf("%g and %g average is %g", x, y, average(x, y));
return 0;
}
函数参数
函数的参数分为实际参数和形式参数
实际参数:真实传给函数的参数,叫做实际参数。实际参数可以是常量、变量、表达式、函数。
实际参数是出现在函数调用中的表达式
形式参数:形式参数是指函数名后面括号中的变量,形式参数只有在函数被调用时才会分配空间,所以叫做形式参数。形式参数在函数用完之后自动销毁,因此,形式参数直在函数中有用。
形式参数出现在函数的定义中,它以假名字来表示函数调用时需要提供的值;
调用函数时:计算出每个实际参数的值,并把它赋给形式参数。在函数执行过程中,对形式参数的改变不会影响实际参数的值,这是因为形式参数中包含的是实际参数值的副本。
形式参数的修改不会影响实际参数的值。当实际参数是以地址的形式传递时,实际参数的值会被改变。
函数调用
函数的调用有两种方式:传值调用和穿址调用
传值调用:函数的实参和形参分别占有不同的内存块,对形参的改变不会影响实参
传址调用:传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用方式。这种传参方式可以让函数和函数外面的变量建立联系。
1、传值调用,地址不同:
#include <stdio.h>
void swap(int x, int y)
{
printf("%p %p", x, y);
int tem = 0;
tem = x;
x = y;
y = tem;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("%p %p\n", &a, &b);
swap(a, b);
return 0;
}
2、传址调用时,地址相同:
#include <stdio.h>
void swap(int* x, int* y)
{
printf("%p %p", x, y);
int tem = 0;
tem = *x;
*x = *y;
*y = tem;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("%p %p\n", &a, &b);
swap(&a, &b);
return 0;
}
函数的嵌套调用和链式访问
函数和函数之间是可以有机组合的。
嵌套调用:可以在一个函数的定义中使用另一个函数
#include <stdio.h>
void line()
{
printf("nihao\n");
}
void three_line()
{
for (int i = 0; i < 3; i++)
line();
}
int main()
{
three_line();
return 0;
}
链式访问:把一个函数的返回值作位另一个函数的参数
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "hello world";
printf("%d\n", sizeof(arr));
printf("%d\n", strlen(arr));
printf("%d", printf("%d", printf("%d", 43)));
return 0;
}
//%g是打印double类型变量
函数的声明和定义
函数的声明:
告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体存在不存在不知道。
函数的声明一般出现在函数的使用前。要满足先声明后使用。
函数的声明一般放在头文件中。
函数的定义:
函数的定义是指函数功能的具体实现。决定函数是不是存在。
函数递归
递归:韩式自己使用自己。
递归的两个必要条件:1)存在限制条件,当函数满足限制条件后,递归便不再进行。2)每次递归后越来越接近这个限制条件。
1、利用递归计算x的n次
#include <stdio.h>
int power(int x, int y)
{
if (y > 1)
return x * power(x, y - 1);
else
return x;
}
int main()
{
int x = 0;
int n = 0;
scanf("%d %d", &x, &n);
printf("%d", power(x, n));
return 0;
}
2、利用递归接受一个整型值,按顺序打印它的每一位。
#include <stdio.h>
void print(int x)
{
if (x > 9)
{
print(x / 10);
}
printf("%d ", x % 10);
}
int main()
{
int n = 0;
scanf("%d", &n);
print(n);
return 0;
}
3、编写函数,求字符串的长度
#include <stdio.h>
int my_strlen(char* n)
{
int count = 0;
while (*n != '\0')
{
count++;
n++;
}
return count;
}
int main()
{
char arr[20] = { 0 };
scanf("%s", arr);
int ret = my_strlen(arr);
printf("%d\n", ret);
return 0;
}
#include <stdio.h>
int my_strlen(char* n)
{
if (*n == '\0')
return 0;
else
return 1 + my_strlen(n + 1);
}
int main()
{
char arr[20] = { 0 };
scanf("%s", arr);
int len = my_strlen(arr);
printf("%d", len);
return 0;
}
4、求n的阶乘
#include <stdio.h>
int fac(int n)
{
if (n < 2)
return 1;
else
return n * fac(n - 1);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = fac(n);
printf("%d", ret);
return 0;
}
5、求第n斐波那契额数
#include <stdio.h>
int fib(int n)
{
if (n < 3)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = fib(n);
printf("%d", ret);
return 0;
}
6、汉诺塔问题
#include <stdio.h>
void move(char pos1, char pos2)
{
printf(" %c--->%c ", pos1, pos2);
}
void hanoi(int n, char pos1, char pos2, char pos3)
{
if (n == 1)
{
move(pos1, pos3);
}
else
{
hanoi(n - 1, pos1, pos3, pos2);
move(pos1, pos3);
hanoi(n - 1, pos2, pos1, pos3);
}
}
int main()
{
hanoi(1, 'A', 'B', 'C');
printf("\n");
hanoi(2, 'A', 'B', 'C');
printf("\n");
hanoi(3, 'A', 'B', 'C');
return 0;
}
7、青蛙跳台阶问题
#include <stdio.h>
int jump(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else if (n == 2)
return 2;
else
return jump(n - 1) + jump(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = jump(n);
printf("%d", ret);
return 0;
}
8、快速排序
#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int tem = 0;
tem = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tem;
}
}
}
}
int main()
{
int arr[] = { 3,4,5,6,7,8,9,10,1,2, };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}