函数的分类
1.库函数
2.自定义函数
库函数
把一些常用的功能实现成库函数,集成库由C语言直接提供。方便程序员开发利用。
学习库函数通常使用这个网站:http://www.cplusplus.com
C语言常用的库函数分为以下几类:
一般需要了解库函数所需要的头文件.h使用时需要的,参数类型,返回类型,使用方法。
例子: strcpy
memset
小知识点:siezof的返回类型是size_t(整型)
自定义函数
当需要通过自定义函数来改变主函数中变量的值时,要将实际参数的地址传给自定义函数才行
void Swap2(int *px, int *py)
{
int tmp = 0;
tmp = *px;
*px = *py;
*py = tmp; }
int main()
{
int num1 = 1;
int num2 = 2;
Swap1(num1, num2);
printf("Swap1::num1 = %d num2 = %d\n", num1, num2);
Swap2(&num1, &num2);
printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
return 0; }
实际参数
当实际参数传给形式参数时,形式参数只是实际参数的临时拷贝
形式参数
当实际参数传一个数组名字时,相当于传一个地址过来,要用指针来接收,具体指针类型取决于数组类型,char*或int* ;形式参数也可以写成(char/int arr【】);当写成指针时(char/int*str)自定义函数中的数组也可以直接用指针名如: str[ ];
传了数组第一个元素的地址过来后剩下元素地址也是有规律的,因此可以推出其他元素出来;str++,指向下一个元素。*str取第一个元素值;
注意:当*str要加1时;只能写成(*str)++或*str=*str+1;因为运算符优先级缘故。
内存下比较形式参数和实际参数
实际参数和形式参数都有属于自己的地址
传值调用
不会改变实际参数的值
传址调用
形式参数可以操作实际参数
练习:
函数的嵌套调用
可以嵌套调用当不可以嵌套定义
void new_line()
{
printf("hehe\n");
}
void three_line()
{
int i = 0;
for(i=0; i<3; i++)
{
new_line();
}
}
int main()
{
three_line();
return 0; }
链式访问
#include <stdio.h>
#include <string.h>
int main()
{
char arr[20] = "hello";
int ret = strlen(strcat(arr,"bit"));//这里介绍一下strlen函数
printf("%d\n", ret);
return 0; }
#include <stdio.h>
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
//结果是啥?
//注:printf函数的返回值是打印在屏幕上字符的个数
return 0; }
printf每打印出一个元素就返回1,43是两个元素返回2;打印结果4321
函数的声明和定义
函数声明:一般在.h头文件中;主要任务就是介绍函数的使用方法,返回类型,使用参数类型。
1.这是在.h头文件声明函数的方法;在自己源文件中定义的函数也这样声明。
int Add(int ,int );//声明
int main()
{
int a=2,b=3;
printf("%d",Add(a,b));
}
int Add(int x,int y)//定义
{
return x+y;
}
2.用别人工程的函数时 在源文件中声明函数的方法。
函数声明时可以不用写参数变量名,类型一定要写
函数定义: 一般在.c源文件中;主要任务就是编写代码组成工具;
一般情况下多个程序员工作时需要互相协助,因此要使用别人的代码时 直接将别人的.h文件和.c源文件或者lib文件弄到自己的工程文件中,然后在自己的.c源文件中进行声明如:#include"Add.h"
当不想让对方看到自己的源程序文件时可以将lib文件传给他。在使用别人的lib文件时也需要在自己的源程序文件中声明。如:#pragma comment (lib,"add.lib") 这是导入静态库的写法
生成静态库(lib文件)方法:
函数的递归
理解: 递归
传递参数时,参数每一次进入函数值都会改变,无限接近限制条件
if 判断条件:用来设置限制条件
回归:倒着将值返回 回来
void print(int n)
{
if (n > 9)
{
print(n/10);
}
printf("%d ", n % 10);
}
int main()
{
unsigned int num = 0;
scanf("%d", &num);//1234
print(num);//print函数可以把num的每一位按照顺序打印出来
}
print(1234)
print(123) 4
print(12) 3 4
print(1) 2 3 4
1 2 3 4
int my_strlen(char* str)
{
if (*str != '\0')
return 1 + my_strlen(str+1);
else
return 0;
}
int main()
{
char arr[] = "abcd";
//char* str = arr;
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
int fib(int n) {
if (n <= 2)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
缺点:容易栈溢出,计算量大
//1 1 2 3 6 9 15
int a = 1, b = 1, c = 0;
int count = 2, n = 0;
scanf("%d", &n);
while (n>2)
{
c = a + b;
a = b;
b = c;
count++;
if (count == n)
{
printf("%d", c);
break;
}
}
递归题
当str[ ]=“abcdef”;
str可以访问“abcdef”;
str+1访问bcdef字符