练习(1)
目录
1.有趣的计算题
请问循环多少次?
#include<stio.h>
int main()
{
int i = 0;
int k = 0;
for(i = 0,k = 0; k = 0; i++,k++)
{
k++;
}
return 0;
}
答:0次,k = 0为赋值表达式,其结果为0 。0为在计算机识别时代表假,判断结果为假,程序不执行,所以答案为0次。
注:
1.在编写代码的过程中,我们时常会不仅以将相等关系运算符与赋值运算符误用混淆。在使用时应注意这一点。
2.计算机中,0为假,非0为真
2.在一个有序数组中查找具体的某个数字(二分查找)
1.前置需求:有序
2.折中查找法
原理讲解与优势:
<1>优势:大大减少查找次数,提高效率(n个数,至多查找 log 2 ( n ) \log_2(n) log2(n)次)
<2>原理: 最小数与最大数求平均值,以平均值与需要查找的数做对比,一次排除一半的数。
#include<stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//有序数组
int sz = sizeof(arr)/sizeof(arr[0]);
int i = 7;
int flag = 0;
int left = 0;
int right = sz - 1;
int mid = 0;
while(left <= right)
{
mid = (left + right) / 2;
//优化1:(left / 2) + (right / 2);(可能死循环,+1)
//优化2:(right - left) / 2 + left;
//数字过大,求和后超过int类型范围
if(i > arr[mid])
//数组的下标
{
left = mid;
left++;
}
else if(i < arr[mid])
{
right = mid;
right--;
}
else if(i == arr[mid])
{
printf("找到了,下标为%d\n",mid);
flag = 1;
break;
}
}
if(flag != 1)
{
printf("没找到\n");
}
return 0;
}
3.编写代码,实现字符从两端移动,向中间汇聚
1.创建两个数组存放字符
2.将数组第个数组的元素依次赋值给第二个数组的元素
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
int main()
{
char arr1[] = "###########";
char arr2[] = "Hello World";
int m = 0;
int n = sizeof(arr1) / sizeof(arr1[0]) - 2;
//注:sizeof操作符于strlen()库函数的区别
//sizeof计算数组所占内存长度,包含'\0'
//strlen()计算字符串长度,不包含'\0'
while(m <= n)
{
printf("%s\n",arr1);
arr1[m] = arr2[m];
m++;
arr1[n] = arr2[n];
n--;
Sleep(1000);//1000毫秒
system("cls");
}
printf("%s\n",arr1);
return 0;
}
4.模拟用户登录,只能登录三次
注:字符串比较,strcmp()
#include<stdio.h>
#include<string.h>
int main()
{
int m = 0;
char password[20] = { 0 };
int flag = 0;
for (m = 0; m < 3; m++)
{
printf("请输入密码>:");
scanf("%s", password);
if (0 == strcmp("123456", password))
{
printf("登录成功\n");
flag = 1;
break;
}
else
{
if (2 == m)
{
break;
}
printf("输入错误,请再次尝试\n");
}
}
if (0 == flag)
{
printf("已达尝试次数上限,确认失败\n");
}
return 0;
}
5.猜数字游戏的实现
注:程序设计的思路
1.菜单
2.游戏的实现
<1>随机数的生成(范围限制,随机)
<2>判断
3.可选择多次游戏
#include<stdio.h>
#include<time.h>
void meuo()
{
printf("**************************\n");
printf("*** start:1 *** exit:0 ***\n");
printf("**************************\n");
}
void game()
{
int num = rand() % 100 + 1;
//随机数的生成,'%100'生成1到99之间的数
int guess = 0;//玩家猜测的数
while(1)
{
scanf("%d",&guess);
if(guess > num)
{
printf("猜大了\n");
}
else if(guess < num)
{
printf("猜小了\n");
}
else
{
printf("猜对了\n");
break;
}
}
}
int main()
{
int input = 0;//控制游戏的开始于结束
do//多次游戏
{
//声明随机数的生成起点
srand((unsigned int)time(NULL));
meuo();
//菜单
printf("请选择>:");
scanf("%d",&input);
switch(input)//游戏进行的流程
{
case 1://进入
printf("猜数字游戏\n");
game();//游戏的实现
case 0://退出
break;//跳出分支语句
default:
printf("选则错误,请重新选择\n");
}
}while(input);//1继续游戏,0结束游戏
return 0;
}
6.打印出1到100之间的素数
注:只能被1和其本身整除的数
1.生成1到100之间的数
2.判断每一个数是否为素数
<1>试除法(将1到其本身的数依次做除法)
<2>每一个数必定可以被1与其自身整除,所以从2开始试除到(n-1)
<3>优化1:所有素数都是奇数(num + 2)
<4>优化2 :m < (num / 2)
<5>优化3:一个数若能被整除则它小于被除数(num)的二次方必定也能被整除
因此可以只用试除到根号n便能排查完成。
#include<stdio.h>
#include<math.h>
int main()
{
int num = 0;
int m = 0;
int flag = 0;
int count = 0;
for(num = 1; num <= 100; num++)
{
flag = 0;
//err:m < sqrt(num)
for(m = 2; m <= sqrt(num); m++)
{
if(num % m == 0)
{
flag = 1;
break;
}
}
if(0 == flag)
{
printf("%d ",num);
count++;
}
}
printf("\n%d\n",count);
return 0;
}
7.打印出1000年到2000年之间的闰年
1.输出1000到2000之间的年份
2.能被4整除但不能被100整除,或者可以被400整除的年份
#include<stdio.h>
int main()
{
int year = 0;
for(year = 1000; year <= 2000; year++)
{
if((0 == year % 4 && 0 != year % 100) || year % 400 )
//逻辑运算符,且(&&),或(||)
{
printf("%d ",year);
}
}
return 0;
}
8.求出两个数的最大公约数
1.两个数都能整除的数
2.试除法
3.优化:辗转相除法
辗转相除法原理介绍:
#include<stdio.h>
//试除法
int main()
{
int m = 0;
int n = 0;
int num = 0;
int max = 0;
scanf("%d %d",&m,&n);
for(num = 1; num <= m; num++)
{
if(0 == m % num && 0 == n % num)
{
max = num;
}
}
printf("%d\n",max);
return 0;
}
//辗转相除法
//m n r
//15 % 20 = 15
//m <- n,n <- r
//20 % 15 = 5
//同上操作
//15 % 5 = 0
//最大公约数为5(n)
int main()
{
int m = 0;//第一个数
int n = 0;//第二个数
int r = 0;//余数
scanf("%d %d",&m,&n);
while(r)
{
r = m % n;
if(r != 0)
{
m = n;
n = r;
}
}
printf("%d\n",n);
return 0;
}