当前位置:主页 > 查看内容

【C语言学习笔记——3】

发布时间:2021-06-12 00:00| 位朋友查看

简介:声明由于作者水平有限本文难免有错误和不准确之处本人也很想知道这些错误恳望读者批评指正。 【联系方式】1583598623qq.com 【更新记录】2021年4月11日第一次更新 【勘误记录】暂无 1.看一个有趣的getchar程序段还未输入Y/N回车键一敲立刻显示确认失败why in……

声明:由于作者水平有限,本文难免有错误和不准确之处,本人也很想知道这些错误,恳望读者批评指正。

【联系方式】1583598623@qq.com
【更新记录】2021年4月11日(第一次更新 )
【勘误记录】暂无

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;

}

在这里插入图片描述

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;
}
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
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文

  • 周排行
  • 月排行
  • 总排行

随机推荐