从代码中学习——1

1.数组数据录入

有误代码:

int main()

{  
     int i = 0;
     int fig[4] = { 0 };
     scanf("%d", &fig[i]); //fig也可当做地址,但只能作为整个数组地址,&fig则是说的数组里具体一个数的地址
     int max = fig[0];
     while (i < 4) //这里只有第一个数进入循环
     {
         if (fig[i] > max)
             max = fig[i];
         i++;
     }
     printf("%d", max);

     return 0;
}

scanf函数这里还要用个while循环才能输入数组内的4个数。

正确如下:

	int main()

	{

	    int fig[4] = { 0 };
	    int i = 0;
	    while (i < 4)
	    {
	        scanf("%d", &fig[i]);
	        i++;
	    } //循环录入4个数字
	    i = 1;
	    int max = fig[0];
	    while (i < 4)
	    {
	        if (fig[i] > max)
	            max = fig[i];
	        i++;
	    } //循环比较4个数字
	    printf("%d", max);
	
	    return 0;
	}

2. 字母大小写转换

2.1 版本1

//将大小写输入后进行相互转化
	char ch = 0;
	while (scanf("%c", &ch) == 1) {
		if (ch >= 'a' && ch <= 'z') {
			printf("%c\n", ch - 32);
		}
		else {
			printf("%c\n", ch + 32);
		}
		//int getchar();//这样相当于定义了一个变量,getchar没有起到作用
		//getchar返回值为int类型,如果没有返回类型会报警告
		int ret = getchar();//光标会一直停在此处,输入一个值后getchar便会取走一个,所以要注意取值顺序
		//1. 后续\n为不可少项,因为需要\n确定开始执行
		//2. 输入ab\n(此处\n为键入enter)会得到a*,因为b被getchar拿走后,剩余a通过if转为A,一次循环结束,\n通过第
		//	 二次循环进入else,被转换为*,具体过程可通过调试了解
		//3. 输入\n(键入enter)会导致后续输入字符转换为*,\n在else处变为*后光标停在getchar处,下一次输入字符a\n时,
		//	 a先被getchar拿走,剩余空格被转换为*,再次输入一个\n或输入偶数个字符如ab可正常转大小写 

2.2 版本2

	char ch = 0;
	while(scanf("%c",&ch) == 1) {
		if(ch >= 'a' && ch <= 'z') {
			printf("%c\n",ch - 32);
		}
		else if(ch >= 'A' && ch <= 'Z'){
			printf("%c\n",ch + 32);
		}
		//通过详细得约定就不会出现上面代码中所有字符都会被处理得情况
		//此代码只会将a-z及A-Z进行处理
	}

2.3 知识拓展(scanf和getchar)

2.3.1 scanf函数

scanf函数从标准输入流stdin读取数据,并将数据写入参数给定的位置。每个参数都必须是指向与格式中的类型说明符相对应的类型的变量的指针。
它的返回值是返回成功转换和分配的字段数,即是返回多少字段,一个类型可表示一个字段
例如:

	int a = 0,b = 0,c = 0;
	int ret1 = 0,ret2 = 0;
	ret1 = scanf("%d",&a);
	ret2 = scanf("%d %d",&a,&b);
	printf("%d",ret1);//结果为1
	printf("%d",ret2);//结果为2

2.3.2 getchar函数

getchar函数即为从stdin(标准输入)中获取一个字符
它的返回值为返回读取的字符。为了指示读取错误或文件结束条件,getchar返回EOF。getchar,使用ferror或feof来检查错误或文件结尾。

	char ch = 0;
	while(scanf("%c",&ch) == 1) {
		if(ch >= 'a' && ch <= 'z') {
			printf("%c\n",ch - 32);
		}
		else{
			printf("%c\n",ch + 32);
		}
	int ret = getchar();
	printf("%d",ret);
  • 第一次输入一个\n进去后会在else处被使用,stdin内容为空,光标会停在getchar处不向后运行,等待新的字符录入
  • 第二次输入\n后,从getchar处开始运行,\n在getchar处被取走,ret值为\n为对应ASCII码值,ret答应结果为10,向后进入while后表达式,scanf录入新的值
  • 当输入一个字符+\n(enter即输入了\n)时,字符在if…else处被取走,\n在getchar处被取走,此时ret值也为10,向后运行进入while后表达式,scanf录入新的值

3.判断是否为字母

方法1

	char ap = 0;
	while (scanf(" %c", &ap) == 1) {
		if ((ap >= 'a' && ap <= 'z') || (ap >= 'A' && ap <= 'Z')) {
			printf("%c is an alphabet\n", ap);
		}
		else {
			printf("%c isn't an alphabet\n", ap);
		}
	getchar();
	}

此处getchar()的作用在于抓走\n,避免影响后面字符的判断

方法2:

	//判断输入内容是否为字母
	char ap = 0;
	//%c前面加空格
	//意为跳过下一个字符之前所有空白字符
	while (scanf(" %c", &ap) == 1) {
		if ((ap >= 'a' && ap <= 'z') || (ap >= 'A' && ap <= 'Z')) {
			printf("%c is an alphabet\n", ap);
		}
		else {
			printf("%c isn't an alphabet\n", ap);
		}
	}

此处%c前面加空格的意义在于屏蔽空白字符\n,等同于方法1的getchar()

4.pow使用

	#include<stdio.h>
	#include<math.h>

	int main(){
		//求五位数中所有得Lily Number
		//Lily Number指的是将任意数字从中间拆分,拆分后乘积之和等于其本身
		//如655=6*55+65*5
		int i = 0;
		for (i = 10000;i < 100000;i++) {
			int sum = 0;
			int j = 0;
			for (j = 1; j <= 4; j++) {
	
				int k = (int)pow(10, j);
				//pow返回double类型,需用强制类型转换为int类型
				//pow需要使用头文件<math.h>
				sum += (i % k) * (i / k);
				//sum += i % k * i / k;//此处不加括号,优先级无法准确确定
			}
			if (sum == i) {
				printf("%d ", i);
			}
		}
	}
  • pow是求幂函数,格式为double pow( double x, double y ); 意为求xy的值
  • 有上述内容可知,pow返回的是double类型的值,故在使用时可能需要将其转化为需要的类型 (如int型)

5.统计输入值中二进制位1的个数

5.1 计数计算

思路:
等同于十进制数转化为二进制数;将输入的数除2,观察是否余1,是则加1,否则不加

	unsigned int num = 0;
	int count = 0;
	scanf("%d",&num);
	while(num){
		if(num % 2 == 1){
			count++;
		}
		num /= 2;
	}
	printf("%d",n);

5.2 按位与计算

思路:
计算机中数字存储都是以二进制存储,可以利用位运算将存储的数进行移位和运算

5.2.1 移位配合与运算

	int num = 0;
	int count = 0;
	int i = 0;
	scanf("%d",&num);
	for(i = 0;i < 32;i++){
		if(((num >> i) & 1) == 1){
			count++;
		}
	}
	printf("%d",count);

5.2.2 只使用与运算

	int num = 0;
	int count = 0;
	while(num){
		n = n & (n-1);
		count++;
	}
	printf("%d",count);

原理解析:
int n = 15;
n = n & (n-1)
1111 & 1110 = 1110
1110 & 1101 = 1100
1100 & 1010 = 1000
1000 & 0111 = 0000
与运算的特点是0&0 = 0&1 = 0,1&1 = 1;数字n在计算机中存储的格式是二进制位,当n-1时,n对应二进制位最后一位减1,如果最后一位为0,则向前借一位,n&(n-1)时,n-1的最后一位与n的二进制最后一位不一致(如果向前借位则被借位也会不一致),故前面的二进制数不变,后面的会变为0,如此可将二进制中的1逐渐消除,每运算一次消除1个1,当n=0时计算运算结果即为n的二进制中1的个数

5.3 知识拓展

键入两个值,比较他们对应二进制表达式中不同位的个数

	int m = 0;
	int n = 0;
	int count = 0;
	scanf("%d %d",&m,&n);
	//异或操作,将不同的值相比较并转为1;如001^110 = 111
	int calc = m^n;
	//统计calc中1的个数
	while(ret){
		ret = ret & (ret - 1);
		count++;
	}
	printf("%d",count);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值