C【函数】

1.常用API

1.strcpy:#include

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;
}

C【函数】_第1张图片

C【函数】_第2张图片

3.函数的参数

3.1 实际参数(实参)

C【函数】_第3张图片

C【函数】_第4张图片

3.2 形式参数(形参)

C【函数】_第5张图片

C【函数】_第6张图片

4.函数的调用

4.1 传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参

2.传址调用

  • 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
  • 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操 作函数外部的变量。

3.练习

1. 写一个函数可以判断一个数是不是素数。

//是素数返回1,不是素数返回0
#include 

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;
}

C【函数】_第7张图片

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 
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 
#include 
int main()
{
    char arr[20] = "hello";
 int ret = strlen(strcat(arr,"bit"));//这里介绍一下strlen函数
 printf("%d\n", ret);
 return 0;
}
#include 
int main()
{
    printf("%d", printf("%d", printf("%d", 43)));
    //结果是啥?
    //注:printf函数的返回值是打印在屏幕上字符的个数
    return 0;
}

6.函数的声明和定义

6.1 函数声明

C【函数】_第8张图片

6.2 函数定义

C【函数】_第9张图片

C【函数】_第10张图片

7.函数递归

C【函数】_第11张图片

C【函数】_第12张图片

7.1 递归的两个必要条件

存在限制条件,当满足这个限制条件的时候,递归便不再继续。

每次递归调用之后越来越接近这个限制条件

7.2 练习

C【函数】_第13张图片

C【函数】_第14张图片




C【函数】_第15张图片

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;
}

C【函数】_第16张图片

C【函数】_第17张图片

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个斐波那契数。(不考虑溢出)

C【函数】_第18张图片

斐波那契数列
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;
}

C【函数】_第19张图片

你可能感兴趣的:(c语言,开发语言)