#include <stdio.h>
int test(int a, int b)
{
return a + b;
}
void fun()
{
int ret = test(2, 3);
printf("hehe\n");
}
int main()
{
return 0;
}
注: 函数可以嵌套调用,但是不存在嵌套定义
//以下写法是错误的
#include <stdio.h>
int test(int a, int b)
{
return a + b;
void fun()
{
printf("hehe\n");
}
}
int main()
{
return 0;
}
把一个函数的返回值作为另外一个函数的参数。
#include <stdio.h>
#include <string.h>
int main()
{
//int len = strlen("abcdef");
//printf("%d\n", len);
//链式访问
printf("%d\n", strlen("abcdef"));
return 0;
}
#include <stdio.h>
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
return 0;
}
//4321
#include <stdio.h>
int main()
{
printf("%d ", printf("%d ", printf("%d ", 43)));
return 0;
}
//43 3 2
#include <stdio.h>
//函数声明
//int Add(int, int);
int Add(int x, int y);//这两种写法都可以
int main()
{
int a = 0;
int b = 0;
//输入
scanf("%d %d", &a, &b);
//加法
int c = Add(a, b);//函数调用
//打印
printf("%d\n", c);
return 0;
}
//函数的定义
int Add(int x, int y)
{
return x + y;
}
函数的定义是指函数的具体实现,交待函数的功能实现。
#include <stdio.h>
//函数的定义-定义是一种特殊的声明
int Add(int x, int y)
{
return x + y;
}
int main()
{
int a = 0;
int b = 0;
//输入
scanf("%d %d", &a, &b);
//加法
int c = Add(a, b);//函数调用
//打印
printf("%d\n", c);
return 0;
}
//add.h
//函数的声明
int Add(int x, int y);
//add.c
//函数定义
int Add(int x, int y)
{
return x + y;
}
//test.c
#include <stdio.h>
#include "add.h"
int main()
{
int a = 0;
int b = 0;
//输入
scanf("%d %d", &a, &b);
//加法
int c = Add(a, b);//函数调用
//打印
printf("%d\n", c);
return 0;
}
再举一个简单的例子:假设有一位程序员写了一个能够求两数相加之和的函数,他想卖给别人使用,但又不想让别人看到他的源代码,他应该怎么做呢?
首先,他需要写一个.h文件(在.h文件中声明函数,同时可以通过注释来解释函数的功能、参数和返回值)
//add.h
//函数
//函数的功能
//参数
//返回值
int Add(int x, int y);
接着,他需要写一个.c文件
int Add(int x, int y)
{
return x + y;
}
最后,将其改为静态库;之后就可以将静态库和头文件卖给别人。(买方买到静态库后打开查看只能看到一堆乱码,因为代码已经转换为二进制了,不需要担心源代码会被看到。)
买方买到他的静态库和头文件后,先将其添加到他所写的项目的文件夹中,之后用如下代码:
#include <stdio.h>
#include "add.h"
//.lib - 静态库
//导入静态库
#pragma comment(lib, "add.lib")
int main()
{
int a = 0;
int b = 0;
//输入
scanf("%d %d", &a, &b);
//加法
int c = Add(a, b);//函数调用
//打印
printf("%d\n", c);
return 0;
}
//以下就是一个简单的递归;但是这个递归会死递归,导致栈溢出
#include <stdio.h>
int main()
{
printf("hehe\n");
main();
return 0;
}
以下为两个例题,用以更好地理解递归的两个必要条件
接收一个整型值(无符号),按照顺序打印它的每一位。 例如: 输入:1234 输出: 1 2 3 4
void print(unsigned int n)//1234
{
if (n > 9)
{
print(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
unsigned int num = 0;
//输入
scanf("%d", &num);
print(num);
return 0;
}
编写函数不允许创建临时变量,求字符串的长度。
首先,我们先写一个求字符串长度的代码
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "abc";
int len = strlen(arr);
printf("%d\n", len);
return 0;
}
上面用的是库函数,那能不能自己编写一个函数来求字符串长度呢
#include <stdio.h>
int my_strlen(char* s)
{
int count = 0;
while (*s != '\0')
{
count++;
s++;
}
return count;
}
int main()
{
char arr[] = "abc";
//[a b c \0]
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
最后,再加上条件:不允许创建临时变量
//my_strlen("abc")
//1+my_strlen("bc")
//1+1+my_strlen("c")
//1+1+1+my_strlen("")
//1+1+1+0
//3
//
//递归
#include <stdio.h>
int my_strlen(char* s)
{
if (0 == *s)
{
return 0;
}
else
{
return 1 + my_strlen(s + 1);
}
}
int main()
{
char arr[] = "abc";
//[a b c \0]
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
求n的阶乘。(不考虑溢出)
//n! = 1*2*3*4...*n
//循环(迭代)
#include <stdio.h>
int Fac(int n)
{
int r = 1;
int i = 0;
for (i = 1; i <= n; i++)
{
r = r * i;
}
return r;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fac(n);
printf("%d\n", ret);
return 0;
}
//递归
#include <stdio.h>
int Fac(int n)
{
if (n <= 1)
{
return 1;
}
else
{
return n * Fac(n - 1);
}
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fac(n);
printf("%d\n", ret);
return 0;
}
求第n个斐波那契数。(不考虑溢出)
//求第n个斐波那契数
//1 1 2 3 5 8 13 21 34 55 ...
//前2个的数的和是第三个数
#include <stdio.h>
int Fib(int n)
{
if (n <= 2)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;
}
//迭代写法
#include <stdio.h>
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n >= 3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;
}
但是我们在使用递归的时候会发现以下问题:
问题原因:
如何解决上述的问题:
以下是对于第二点的一个具体举例:
求n的阶乘。(不考虑溢出)
#include <stdio.h>
int Fac(int n)
{
static int result = 1;
if (n <= 1)
{
return result;
}
else
{
result *= n;
return Fac(n - 1);
}
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fac(n);
printf("%d\n", ret);
return 0;
}
提示:
1, 许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。 2. 但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差些。 3. 当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销。