声明:由于作者水平有限,本文难免有错误和不准确之处,本人也很想知道这些错误,恳望读者批评指正。
【联系方式】1583598623@qq.com
【更新记录】2021年4月12日(第三次更新 )
【勘误记录】暂无
文章目录
-
-
- 1.看一个有趣的getchar程序段,还未输入Y/N,回车键一敲立刻显示确认失败!why?
- 2.对比for循环中的break和continue,for循环中的continue直接跳到调整部分,与while中的continue(可能死循环)有所不同。
- 3.小心代码的省略
- 4.请问如下循环分别循环几次?
- 5.(二分法)在一个有序数组中查找具体的某个数字n
- 6.实现输出逐渐显示"welcome to China"
- 7.假设正确密码是字符串"123456",验证密码的正确性
- 8.猜数游戏实现:自动产生一个1-100的随机数,猜数字,会提示你猜大还是猜小,知道猜对了停止
- 9.编写程序数一下 1到 100 的所有整数中出现多少个数字9,需要注意有两部分组成,个位数的9和十位数的9.
- 10.计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,打印出结果
- 11.求十个整数中最大值
- 12.在屏幕上输出9*9乘法口诀表
- 13.(补充上面第5点二分查找内容)
-
1.看一个有趣的getchar程序段,还未输入Y/N,回车键一敲立刻显示确认失败!why?
int main()
{
char password[20]= {
0 };
printf("请输入密码:>");
scanf("%s", password);
printf("确认密码(Y/N:>");
int ch = getchar();
//字符表达式也算是整形表达式,因为字符存储和运算的时候,都是ASCII码值。
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
因为scanf、getchar这类输入函数,都是从输入缓冲区当中读取,不是直接从键盘读取,在上例中,键盘敲入“123456\n”(这里\n对应回车键),123456被scanf拿走,\n很自然的被getchar拿走放到ch内,所以并没有等待让我们输入Y/N。
所以,如何处理??? 加一个getchar把回车读走即可,但是真的足够吗?
int main()
{
char password[20]= {
0 };
printf("请输入密码:>");
scanf("%s", password);
printf("确认密码(Y/N:>");
//清理缓冲区
getchar();
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
输入123456\n没有问题,但是输入123 456再次不行,why?
因为一个getchar()只能处理掉一个缓存区字符,一个空格就消耗掉了,可以考虑加个循环。
int main()
{
char password[20]= {
0 };
char tmp;
printf("请输入密码:>");
scanf("%s", password);
printf("确认密码(Y/N:>");
//清理缓冲区
//getchar();
while ((tmp = getchar()) != '\n')
{
;
}
int ch = getchar();//注意是int
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
2.对比for循环中的break和continue,for循环中的continue直接跳到调整部分,与while中的continue(可能死循环)有所不同。
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d", i);
}
}
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
//break;
continue;
printf("%d", i);
}
}
3.小心代码的省略
程序段1
int main()//输出9个hehe
{
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("hehe\n");
}
}
return 0;
}
程序段2
int main()//只输出3个hehe,因为内部for循环里j第二次循环就没有被初始化
{
int i = 0;
int j = 0;
for (; i < 3; i++)
{
for (; j < 3; j++)
{
printf("hehe\n");
}
}
return 0;
}
4.请问如下循环分别循环几次?
int main()
{
int i = 0;
int k = 0;
for (i = 0; k = 0; i++, k++)//循环0次,k=0为假
{
k++;
printf("%d", k);
}
return 0;
}
int main()
{
int i = 1;
do
{
if (i == 5)
continue;//continue导致输出前四个数后便死循环
printf("%d", i);
i++;
} while (i <= 10);
return 0;
}
5.(二分法)在一个有序数组中查找具体的某个数字n
int main()
{
int arr[] = {
1,2,3,4,5,6,7,8,9,10 };
int k = 7;//要查找的数字
int sz = sizeof(arr) / sizeof(arr[0]);//数组的元素个数
int left = 0;
int right = sz - 1;//为什么减一,因为第一个从0开始,减一后才是最右边元素下标
while (left<=right)
{
int mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid + 1;//加一减一画下图就明白
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
printf("找到了%d", mid);
break;
}
}
if (left > right)
printf("找不到了\n");
return 0;
}
6.实现输出逐渐显示"welcome to China"
int main()
{
char arr1[] = "welcome to China!!!!";
char arr2[] = "####################";
int left = 0;
int right = strlen(arr1) - 1;
while (left <= right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);
Sleep(1000);
left++;
right--;
}
return 0;
}
7.假设正确密码是字符串"123456",验证密码的正确性
int main()
{
int i = 0;
char password[20] = {
0 };
for (i = 0; i < 3; i++)
{
printf("请输入密码:>");
scanf("%s", password);
//不需要特地加取地址符,因为作为数组,数组名就是地址
//if(password=="123456"); 错误,俩字符串不能直接比较,引用strcmp
if (strcmp(password, "123456") == 0)
{
printf("登陆成功\n");
break;
}
}
if (i >= 3)
printf("密码错误三次,已锁定");
return 0;
}
8.猜数游戏实现:自动产生一个1-100的随机数,猜数字,会提示你猜大还是猜小,知道猜对了停止
void menu()
{
printf("*********************************\n");
printf("*************1. play ***********\n");
printf("*************0. exit ***********\n");
printf("*********************************\n");
}
void game()
{
//时间戳time()
int ret = rand()%100+1;//%100的余数是0-99,然后+1,范围就是1-100
//printf("%d\n", ret);
//猜数字
int guess = 0;
while (1)
{
printf("请猜数字:>");
scanf("%d", &guess);
if (guess < ret)
{
printf("猜小了\n");
}
else if (guess > ret)
{
printf("猜大了\b");
}
else
{
printf("恭喜你猜对了\n");
break;
}
}
}
int main()
{
int input = 0;
srand((unsigned int) time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重选\n");
break;
}
} while (input);
return 0;
}
补充说明下:
rand()的作用是生成一个随机数,可是直接调用的话他不够随机,因为他每次开始得位置都一样,那么他就成了固定得数了。
rand他起点固定—srand可以输入一个种子来控制随机数起点,然后就是time函数(时间戳)因为时间一直在变,所以rand()每次起点就不一样了,指针指向时间在强制类型转换成这个unsinge,这样rand()就足够随机了!
9.编写程序数一下 1到 100 的所有整数中出现多少个数字9,需要注意有两部分组成,个位数的9和十位数的9.
int main()
{
int i = 1;
int a = 0;
for (i = 1; i <= 100; i++)
{
if (i % 10 == 9)
a++;
if (i/10 == 9)
a++;
}
printf("一共有%d个数字九",a);
return 0;
}
10.计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,打印出结果
int main()
{
float i = 1;
float ret = 1;
int x = 1;
float sum = 0;
for (i = 1; i <= 100; i++)
{
ret = x * i;
sum += 1 / ret;
x = -x;
}
printf("1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值为%lf", sum);
return 0;
}
11.求十个整数中最大值
int main()
{
int arr[10] = {
0 };
int i = 0;
int max = 0;
for (i = 0; i < 10; i++)
scanf("%d", &arr[i]);
max = arr[0];
for (i = 0; i < 10; i++)
if (arr[i] > max)
max = arr[i];
printf("最大值是%d", max);
return 0;
}
12.在屏幕上输出9*9乘法口诀表
int main()
{
int i = 1;
int j = 1;
for (i = 1; i < 10; i++)
{
printf("\n");
for (j = 1; j <= i; j++)
printf("%d*%d=%2d ", i, j, i * j);//%2d用于对齐美观
}
return 0;
}
13.(补充上面第5点二分查找内容)
编写代码在一个整形有序数组中查找具体的某个数
要求:找到了就打印数字所在的下标,找不到则输出:找不到。
/*
二分查找:
在一个有序的序列中,找某个数据是否在该集合中,如果在打印该数据在集合中的下标,否则打印找不到
具体找的方式:
1. 找到数组的中间位置
2. 检测中间位置的数据是否与要查找的数据key相等
a: 相等,找到,打印下标,跳出循环
b: key < arr[mid], 则key可能在arr[mid]的左半侧,继续到左半侧进行二分查找
c: key > arr[mid], 则key可能在arr[mid]的右半侧,继续到右半侧进行二分查找
如果找到返回下标,否则继续,直到区间中没有元素时,说明key不在集合中,打印找不到
易错点:
1. right的右半侧区间取值,该值决定了后序的写法
2. while循环的条件是否有等号
3. 求中间位置的方法,直接相加除2容易造成溢出
4. 更改left和right的边界时,不确定是否要+1和-1
*/
// 方法一,采用[left, right] 区间
#include <stdio.h>
int main()
{
int arr[] = {
1,2,3,4,5,6,7,8,9,10};
int key = 3;
int left = 0;
int right = sizeof(arr)/sizeof(arr[0])-1; // right位置的数据可以取到
while(left<=right) // right位置有数据,必须要添加=号
{
int mid = left+(right-left)/2;
if(arr[mid]>key) // key小于中间位置数据,说明key可能在左半侧,需要改变右边界
{
right = mid-1; // right位置的数据可以取到,因此right=mid-1
}
else if(arr[mid]<key)// key大于中间位置数据,说明key可能在右半侧,需要改变左边界
{
left = mid+1; // left位置的数据可以取到,因此left=mid+1
}
else
{
printf("找到了,下标是:%d\n", mid);
break;
}
}
if(left>right)
printf("找不到\n");
return 0;
}
// 方法二,采用[left, right) 区间
#include <stdio.h>
int main()
{
int arr[] = {
1,2,3,4,5,6,7,8,9,10};
int key = 3;
int left = 0;
int right = sizeof(arr)/sizeof(arr[0]); // right位置的数据取不到
while(left<right) // right位置没有数据,此处不需要添加=
{
int mid = left+(right-left)/2;
if(arr[mid]>key) // key小于中间位置数据,说明key可能在左半侧,需要改变右边界
{
right = mid; // right位置的数据取不到,因此right=mid,不需要减1
}
else if(arr[mid]<key)// key大于中间位置数据,说明key可能在右半侧,需要改变左边界
{
left = mid+1; // left位置的数据可以取到,因此left=mid+1
}
else
{
printf("找到了,下标是:%d\n", mid);
break;
}
}
if(left>=right)
printf("找不到\n");
return 0;
}
转载:https://blog.csdn.net/weixin_48953972/article/details/115605189
查看评论