1.常用API
1.strcpy:#include<string.h>
char * strcpy ( char * destination, const char * source );
int main()
{
char arr1[] = "bit";
char arr2[20] = "###########";
// bit\0########
strcpy(arr2, arr1);
printf("%s\n", arr2);
//strcpy - string copy - 字符串拷贝
//strlen - string length - 字符串长度有关
return 0;
}
2.menset
void * memset ( void * ptr, int value, size_t num );
int main()
{
char arr[] = "hello world";
memset(arr, '*', 5);
printf("%s\n", arr);
//***** world
return 0;
}
3.参考网站
cppreference.com
2.自定义函数
2.1 函数的组成
ret_type fun_name(para1, * )
{
statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1 函数参数
//定义函数
//形参-形式参数-形式上参数
int 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);
max = get_max(100, 300+1);
max = get_max(100, get_max(3, 7));
printf("max = %d\n", max);
return 0;
}
2.2 交换函数
void Swap1(int x, int y)
{
int tmp = 0;
tmp = x;
x = y;
y = tmp;
}
void Swap2(int* pa, int* pb)
{
int tmp = 0;
tmp = *pa;
*pa = *pb;
*pb = tmp;
}
int main()
{
int a = 10;
int b = 20;
//int tmp = 0;
//
printf("a=%d b=%d\n", a, b);
//调用Swap1函数-传值调用
Swap1(a, b);
//调用Swap2函数
Swap2(&a, &b);
/*tmp = a;
a = b;
b = tmp;*/
printf("a=%d b=%d\n", a, b);
return 0;
}
3.函数的参数
3.1 实际参数(实参)
3.2 形式参数(形参)
4.函数的调用
4.1 传值调用
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参
2.传址调用
- 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
- 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操 作函数外部的变量。
3.练习
1. 写一个函数可以判断一个数是不是素数。
//是素数返回1,不是素数返回0
#include <math.h>
int is_prime(int n)//9
{
//2->n-1
int j = 0;
for(j=2; j<=sqrt(n); j++)
{
if(n%j == 0)
return 0;
}
return 1;
}
int main()
{
//打印100-200之间的素数
int i = 0;
for(i=100; i<=200; i++)
{
//判断i是否为素数
if(is_prime(i) == 1)
printf("%d ", i);
}
return 0;
}
2. 写一个函数判断一年是不是闰年。
//2. 写一个函数判断一年是不是闰年。
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 ", year);
}
}
return 0;
}
3. 写一个函数,实现一个整形有序数组的二分查找。
//本质上arr是一个指针
//3. 写一个函数,实现一个整形有序数组的二分查找
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()
{
//二分查找
//在一个有序数组中查找具体的某个数
//如果找到了返回,这个数的下标。找不到的返回-1
//
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int k = 7;
int sz = sizeof(arr)/sizeof(arr[0]);
// 传递过去的是数组arr首元素的地址
int ret = binary_search(arr, k, sz);
if(ret == -1)
{
printf("找不到指定的数字\n");
}
else
{
printf("找到了,下标是:%d\n", ret);
}
return 0;
}
4. 写一个函数,每调用一次这个函数,就会将 num 的值增加1。
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;
//1
//len = strlen("abc");
//printf("%d\n", len);
//2
printf("%d\n", strlen("abc"));
return 0;
}
5.函数的嵌套调用和链式访问
函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的。
5.1 嵌套调用
#include <stdio.h>
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;
}
函数可以嵌套调用,但是不可以嵌套定义
5.2 链式访问
#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;
}
6.函数的声明和定义
6.1 函数声明
6.2 函数定义
7.函数递归
7.1 递归的两个必要条件
存在限制条件,当满足这个限制条件的时候,递归便不再继续。
每次递归调用之后越来越接近这个限制条件
7.2 练习
int my_strlen(char* str)
{
int count = 0;
while(*str != '\0')
{
count++;
//str+1:表示指向下一个地址
str++;
}
return count;
}
//递归的方法
//把大事化小
//my_strlen("bit");
//1+my_strlen("it");
//1+1+my_strlen("t");
//1+1+1+my_strlen("")
//1+1+1+0
//3
int my_strlen(char* str)//char* str:str数组的首地址
{
if(*str != '\0')//查看插入的数值的第一个是否为'\0'如果不是表示长度至少为1
return 1+my_strlen(str+1);
else
return 0;
}
int main()
{
char arr[] = "bit";
//int len = strlen(arr);//求字符串长度
//printf("%d\n", len);
//模拟实现了一个strlen函数
//arr是数组,数组传参,传过去的不是整个数组,而是第一个元素的地址
int len = my_strlen(arr);
printf("len = %d\n", len);
return 0;
}
7.递归和迭代
1.求n的阶乘。(不考虑溢出)
int Fac1(int n)
{
int i = 0;
int ret = 1;
for(i=1; i<=n; i++)
{
ret *= i;
}
return ret;
}
int Fac2(int n)
{
if(n<=1)
return 1;
else
return n*Fac2(n-1);
}
int main()
{
//求n的阶乘
int n = 0;
int ret = 0;
scanf("%d", &n);
ret = Fac2(n);//循环的方式
printf("%d\n", ret);
return 0;
}
2.求第n个斐波那契数。(不考虑溢出)
斐波那契数列
1 1 2 3 5 8 13 21 34 55 ....
描述第n个斐波那契数的时候
int count = 0;
int Fib(int n)
{
if(n==3)//测试第3个斐波那契数的计算次数
{
count++;
}
if(n<=2)
return 1;
else
return Fib(n-1)+Fib(n-2);
}
50
49 48
48 47 47 46
47 46 46 45 46 45 45 44
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while(n>2)
{
c = a+b;
a = b;
b = c;
n--;
}
return c;
}