简单点_c_lesson9(函数实现相关练习,链式访问、函数调用、多文件)

1.练习

  1. 写一个函数可以判断一个数是不是素数。
  2. 写一个函数判断一年是不是闰年。
  3. 写一个函数,实现一个整形有序数组的二分查找。
  4. 写一个函数,每调用一次这个函数,就会将num的值增加1。

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

#if 0
#include <stdio.h>
#include <windows.h>
//code1:
//int IsPrime(int _num){
//	int i = 0;
//	for(i=2;i<_num;i++){//[2,_num-1]
//	
//		if(_num%i == 0){
//			return 0;
//		}
//	}
//	return 1;
//}

//code2:
//int IsPrime(int _num){
//	int i = 0;
//	for(i=2;i<=_num/2;i++){//[2,_num/2]
//	
//		if(_num%i == 0){
//			return 0;
//		}
//	}
//	return 1;
//}

//code3:
#include <math.h>
int IsPrime(int _num){
	int i = 0;
	for(i=2;i<=(int)sqrt((float)_num);i++){//[2,_num/2]
	
		if(_num%i == 0){
			return 0;
		}
	}
	return 1;
}

int main()
{
	int num = 0;
	printf("请输入一个数:");
	scanf("%d",&num);
	if(1 == IsPrime(num)){
		printf("是素数\n");
	}else{
		printf("不是素数\n");
	}
	system("pause");
	return 0 ;
}

在这里插入图片描述

1.2 写一个函数判断一年是不是闰年

#if 1
#include <stdio.h>
#include <windows.h>

int IsRun(int _year)
{
	return ((_year%4==0)&&(_year%100!=0) || (_year%400 == 0)) ? 1:0;
}
int main()
{
	int year = 0;
	printf("请输入一个数:");
	scanf("%d",&year);
	if(1 == IsRun(year)){
		printf("是闰年\n");
	}else{
		printf("不是闰年\n");
	}
	system("pause");
	return 0 ;
}
#endif

在这里插入图片描述

1.3 写一个函数,实现一个整形有序数组的二分查找。

(1)数组作为函数参数时,如果传入一个数组,真正传参时,发生数组的降维问题,降维成对应的指针,首元素的地址。
降维是通过降低拷贝成本(只拷贝首元素的地址),来提高效率。
(2)只拷贝首元素地址,是因为形参实例化,就是拷贝数据;如果一个数组特别大,拷贝数组,拷贝成本就太大了。
(3)不能再函数中求数组元素的个数,int size = sizeof(_arr)/sizeof(_arr[0]);
其实sizeof(_arr)首元素地址的字节数,为4字节;sizeof(_arr[0])也是4字节。这样数组元素个数一直就是1字节。
所以数组传参不仅要传数组名,还要传数组元素个数。

#if 1
#include <stdio.h>
#include <windows.h>

int BinarySearch(int _arr[],int _size,int _index)
{
	int start = 0;
	int end = _size - 1;

	while(start<=end){
		int mid = (start+end)/ 2;
		if(_index < _arr[mid]){
			end = mid - 1;
		}else if(_index > _arr[mid]){
			start = mid +1;
		}else{
			return mid;
		}
	}
	return -1;
}
int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,10};
	int size = sizeof(arr)/sizeof(arr[0]);
	int index = 0;
	printf("请输入你要查找的数:");
	scanf("%d",&index);
	int ret = BinarySearch(arr,size,index);
	printf("%d\n",ret);
	system("pause");
	return 0 ;
}
#endif

在这里插入图片描述
在这里插入图片描述

1.4 写一个函数,每调用一次这个函数,就会将num的值增加1。

思路:题意就是通过函数来改变main函数中的num值。

#if 1
#include <stdio.h>
#include <windows.h>

int AddNum(int* _num)//int* _num = &num;
{
	return (*_num)++;
}
int main()
{
	int num = 0;
	printf("请输入一个数:");
	scanf("%d",&num);
	printf("%d\n",AddNum(&num));
	printf("%d\n",AddNum(&num));
	printf("%d\n",AddNum(&num));
	printf("%d\n",AddNum(&num));
	system("pause");
	return 0 ;
}
#endif

在这里插入图片描述
在这里插入图片描述

2.链式访问和函数调用

(1)函数调用:一个函数里面调用另外一个函数。
(2)链式访问:把一个函数的返回值作为另外一个函数的参数。(由内而外链式访问)

eg:strcat:char * strcat ( char * destination, const char * source );
(1)将源字符串的副本追加到目标字符串。
(2)目标中终止的空字符将被源的第一个字符覆盖,并且在目标中由两者串联形成的新字符串的末尾包含一个空字符。
(3) printf:返回值为字符的总数

2.1 函数调用

#if 1
#include <stdio.h>
#include <windows.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();
	system("pause");
	return 0;
}
#endif

在这里插入图片描述

2.2 链式访问:由内而外进行计算

#if 1
#include <stdio.h>
#include <windows.h>
#include <string.h>

int main()
{
	//code3:printf返回值为字符的总数
	printf("%d\n",printf("%d",printf("%d",printf("%d",5678))));//5678411
	printf("%d ",printf("%d ",printf("%d ",printf("%d ",5678))));//5678 5 2 2(空格也算)

	//code2:strcat和strlen
	//char arr[32] = "asdfg";
	//char* arr1 = strcat(arr,"world");//asdfgworld
	//printf("%s\n",arr);//arr和arr1一样
	//printf("%s\n",arr1);
	//int ret = strlen(arr1);//asdfgwoeld--10
	//printf("%d\n",ret);
	//printf("%d\n",strlen(strcat(arr,"world")));//asdfgworldworld
	//printf("%s\n",arr);

	//code1:strcat:字符串的拼接
	/*char arr[32] = "asdfg";
	char arr1[32] = "fghjkl";
	char* arr2 = strcat(arr,arr1);//将arr1拼接在arr后面
	printf("%s\n",arr2);*/
	system("pause");
	return 0 ;
}
#endif

在这里插入图片描述
在这里插入图片描述

3.函数的声明和定义

多文件使用:
(1)t.h头文件:变量的声明、函数的声明、头文件的包含
	a.防止头文件被重复包含
		 #ifndef _T_H_
		 #define _T_H_
		 #endif _T_H_
	b.变量的声明:
		eg:extern int global;
		不能写成extern int global = 0;
	c.函数的声明:告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但具体存不存在,需要在源文件中查找。
		eg:int AddNum(int* _num);
	注:函数声明可以忽略extern;而变量声明不能忽略extern。
		函数的声明一般出现在函数使用之前,所以是先声明后使用。
(2)t.c源文件:函数的实现
	a.要包含对应的头文件。一般头文件和源文件同名。
	b.函数的实现都在t.c中实现。
(3)main.c源文件:函数的调用

注:函数的实现和变量的定义只能定义一次,生命可以多次声明。
    函数的定义是指函数的具体实现,交待函数的功能实现。

code1.实现一个计算器
main.c
在这里插入图片描述
t.c
在这里插入图片描述
t.h
在这里插入图片描述
在这里插入图片描述
code2:全局变量的使用
t.c
在这里插入图片描述
main.c
在这里插入图片描述
t.h
在这里插入图片描述

4.遗留的练习

1.分数求和:
	1-1/2+1/3-1/4+...+1/99-1/100的和。
2.乘法口诀表
3.while循环的注意事项。
	while(条件表达式){循环语句}
	while循环中,当条件表达式成立时,才会执行循环语句。每次执行期间,都会对循环因子进行修改(否则就是死循环)。
	修改完成后,如果条件表达式成立,执行循环语句。否则,退出循环。
	因此,while循环条件比循环语句多执行一次。
4.breakcontinue的例子
	break:跳出循环。
	continue:跳出本次循环。

4.1 分数求和

思路:找规律题,奇数项是正的,偶数项是负的。分子都是1,分母是1-100.
1.循环控制分母。
2.flag控制奇数偶数项。
3.将每一项都累加起来。sum =sum + flag * (1.0/i);//注意这块不能写1,浮点数一定要写成1.0
4.返回sum。
#if 1
double Add1()
{
	double sum = 0.0;
	int flag = 1;
	for(int i = 1;i<=100;i++){
		sum =sum + flag * (1.0/i);//注意这块不能写1,浮点数一定要写成1.0
		flag = -flag;
	}
	return sum;
}

float Add2()
{
	double sum = 0.0;
	int flag = 1;
	for(int i = 1;i<=100;i++){
		sum =sum + flag * (1.0f/i);//注意float时,一定要写成1.0f
		flag = -flag;
	}
	return sum;
}
#endif

在这里插入图片描述

4.2 乘法口诀表

思路:两个循环进行控制。
1.i控制行数有多少行。
2.j控制列数有多少列。也就是每行要打印多少个表达式。及其表达式的内容是什么。

#if 1
#include "t.h"
void MulTable()
{
	for(int i=1;i<=9;i++){	
		for(int j = 1;j<=i;j++){
			printf("%d*%d=%d  ",i,j,i*j);
		}
		printf("\n");
	}
}
#endif

在这里插入图片描述

4.3 break、continue的例子

#include "t.h"

int main()
{
	//3.break、continue的例子
	/*
		思路:if是并列的关系。
		      循环体跟a没有关系;a只负责循环更新和条件判定。
			  break跳出循环,break退出本次循环,进入下一次循环。
	*/
	int a = 0;
	int b = 0;
	for(a=1,b=1;a<=100;a++){//a=1,2,3,4,5,6,7,8
		if(b>20){//b=22不成立退出循环
			break;
		}
		if(b%3 == 1){//b=1,4,7,10,13,16,19
			b = b+3;//b=4,7,10,13,16,19,22
			continue;
		}
		b = b-5;
	}
	printf("%d\n",a);//8
	system("pause");
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值