小言_互联网的博客

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

173人阅读  评论(0)

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

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





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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场