练习1:写一个函数 判断一个数是不是素数。
不使用函数:
//不使用函数
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
int main(void)
{
int i;
int k = 2;
int flag = 1; //假设n就是素数
scanf("%d", &i);
while (i > 1)
{
//m = a * b
//a和b中一定至少有一个数字是 <= 开平方m的
//比如 16 = 2*8 = 4*4
//所以下面用sqrt()开平方函数可以减少运算时间
for (k = 2; k <= sqrt(i); k++)
//sqrt()是开平方函数,需要头文件#include<math.h>
{
if (i % k == 0)
{
flag = 0;
break;
//break:只要能被k整除就不是素数,不需要再继续用k++去判断
}
}
if (flag == 1)
{
printf("%d是素数", i);
break;
}
else
{
printf("%d不是素数", i);
break;
}
}
if (i <= 1)
printf("%d不是素数", i);
return 0;
}
使用函数:
//使用函数
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
int is_primer(int n)
{
int k = 2;
int flag = 1; //假设输入的n就是素数
for (k = 2; k <= sqrt(n); k++)
{
if (n % k == 0)
{
flag = 0;
break;
}
}
return flag;
}
int main(void)
{
int i;
scanf("%d", &i);
while (i > 1)
{
if (is_primer(i) == 1)//返回值和1进行比较
{
printf("%d是素数", i);
break;
}
else
{
printf("%d不是素数", i);
break;
}
}
if (i <= 1)
printf("%d不是素数", i);
return 0;
}
练习2:写一个函数,判断是不是闰年
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//一个函数如果不写返回类型,默认返回int类型
void is_leapyear(int n)
{
//能被4整除且不能被100整除的是闰年
//能被400整除的是闰年
if ((n % 4 == 0 && n % 100 != 0) || (n % 400 == 0))
printf("%d是闰年\n", n);
else
printf("%d不是闰年\n", n);
}//void没有返回值 若有返回值忘了写默认返回0
int main(void)
{
int year;
scanf("%d", &year);
is_leapyear(year);
return 0;
}
练习3:写一个函数,实现一个整型有序数组的二分查找。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//返回的是下标,所以函数类型是int类型
int binary_search(int a[], int k, int s)
//此处写a[]只是为了告诉我们这是个数组
{
int left = 0;
int right = s - 1;
while (left <= right)
//left<=right是为了确保中间有元素
{
int mid = (left + right) / 2;
if (a[mid] > k)
{
right = mid - 1;
}
else if (a[mid] < k)
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1; //查完了也找不到
}
int main(void)
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int key = 7; //假设查询7
int sz = sizeof(arr) / sizeof(arr[0]); //求数组元素个数 数组的总大小 除以1个元素的大小 40/4
//找到了就返回找到位置的下标
//找不到返回-1
//创建key_search(),将其找到的值传给ret
int ret = binary_search(arr, key, sz);
//为什么不写arr[],因为能代表数组的只有数组名
//要在arr数组的sz个元素里面找到key
if (-1 == ret)
{
printf("找不到\n");
}
else
{
printf("找到了,下标是:%d\n", ret);
}
return 0;
}
//为什么参数加上sz
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//返回的是下标,所以函数类型是int类型
int key_search(int a[], int k)
//这里的int a[]本质上是个指针
//相当于int key_search(int* a, int k)
{
//所以sizeof(a)=4,sizeof(a[0])=4, sz = 1
int sz = sizeof(a) / sizeof(a[0]);
int left = 0;
int right = sz - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (a[mid] > k)
{
right = mid - 1;
}
else if (a[mid] < k)
{
left = mid + 1;
}
else
{
return mid;
}
}
return -1; //查完了也找不到
}
int main(void)
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int key = 7; //假设查询7
//创建key_search(),将其找到的值传给ret
//数组arr传参,实际传递的不是数组的本身
//仅仅传过去了数组首元素的地址
//上面创建函数的时候相当于这样写的:int key_search(int* a, int k)
int ret = key_search(arr, key);
//要在arr数组的sz个元素里面找到key
if (-1 == ret)
{
printf("找不到\n");
}
else
{
printf("找到了,下标是:%d\n", ret);
}
return 0;
}
为什么不能在函数内部求元素个数呢?
因为数组传参数的时候不会把整个数组传进去,传的仅仅是数组首元素的地。如果函数内部需要参数部分传过来某个数组的元素个数,一定是要在外边求好元素个数,再以参数形式把元素个数传进去。
练习4:编写一个函数,每调用一次这个函数,就会将num的值增加1
改变函数外部的某些变量的时候需要传址
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void add(int* p)
{
(*p)++; //*p相当于num
}
int main(void)
{
int num = 0;
//每调用一次函数,num就会增加1
add(&num);
printf("%d\n", num); //1
add(&num);
printf("%d\n", num); //2
add(&num);
printf("%d\n", num); //3
return 0;
}