【基础练习】n&1==0错在哪儿?

本文源自一道关于质因数分解的编程题目,在讨论如何通过位运算判断数字奇偶性时发现了一个常见误区:位运算符&的优先级较低。文章通过实际案例解释了这一现象,并强调了使用括号来提高代码可读性和正确性的必要性。

这个问题源于一道分解质因数的水题(codevs 1313)

我的源码中有一段是

int n,p;
	scanf("%d",&n);
	if (n&1==0){
		printf("%d",n/2);
		return 0;
	}
可是问题出现了 如果我们输入一个偶数 这个程序块根本不跑

这是一项很奇怪的事 因为快速幂非递归中 我们常用到if(n&1==1)这样的句子

LGA大婶,ZLC神犇纷纷表示无法解答 但鄙人在知乎上找到了答案http://www.zhihu.com/question/20798455

因为这时候我才恍然大悟:位运算优先级非常低 左右移甚至比加减运算优先级还低

没想到的原因 一个是P党时代不用考虑这个 直接and shr这样的 在一个是平时也不大注意 果然还是加括号吧 也能提高程序可读性

——明明如月,何时可掇?忧从中来,不可断绝。



#include <math.h> #include<stdio.h> #include<stdlib.h> #include<time.h> void menu(void); int do_singleadd(); int do_singlesub(); int do_singlemul(); int do_singlediv(); int do_singlemixed(); void do_add(); void do_sub(); void do_mul(); void do_div(); void do_mixed(); int main() { srand(time(0)); int choice; while(1) { menu(); printf("请选择:"); scanf("%d",&choice); if(choice==0) { printf("期待下次运算,再见~"); break; } switch(choice) { case 1:do_add();break; case 2:do_sub();break; case 3:do_mul();break; case 4:do_div();break; case 5:do_mixed();break; default:printf("不符合要求,请重试!!!"); } printf("\n&quot;); } return 0; } void menu() { printf("\n=====~四则运算练习系统~=====\n&quot;); printf("1.加法运算\n&quot;); printf("2.减法运算\n&quot;); printf("3.乘法运算\n&quot;); printf("4.除法运算\n&quot;); printf("5.混合运算\n&quot;); printf("0.退出系统\n&quot;); printf("\n============================\n&quot;); } void circulate_count(int type) { int total=5; int right_count=0; int score=0; float total_time=0; const char*type_name[]={"加法","减法","乘法","除法","混合运算"}; printf("\n======%s练习=====\n&quot;,type_name[type-1]); printf("将进行5道题目,请做好准备!\n&quot;); for(int i=1;i<=total;i++) { printf("\n第%d题",i); time_t start_time=time(NULL); int flag=0; switch(type) { case 1:flag = do_singleadd();break; case 2:flag = do_singlesub();break;; case 3:flag = do_singlemul();break; case 4:flag = do_singlediv();break; case 5:flag = do_singlemixed();break; } time_t end_time=time(NULL); int time_used=(int)difftime(end_time, start_time); total_time += time_used; if(flag==1) { right_count++; score+=20; } printf("用时: %d秒\n&quot;,time_used); } float average_time=total_time/total; printf("\n练习结束!成绩单:\n&quot;); printf("答对题目:%d\n&quot;,right_count); printf("正确率:%.2f\n&quot;,((float)right_count/total)*100); printf("最终得分:%d\n&quot;,score); printf("平均每题用时:%.1f秒\n&quot;,average_time); if (score==100) { printf("太棒了!!!"); } else if (score>=80 && score<=100) { printf("很不啦!"); } else if (score>=60 && score<=80) { printf("还有提升空间~"); } else { printf("需要更多练习哦!\n&quot;); } } int do_singleadd() { int a=rand()%20+1; int b=rand()%20+1; int ans; int attempts=3; int is_correct=0; while(attempts>0){ printf("\n %d+%d=?(还有%d次机会)",a,b,attempts); scanf("%d",&ans); if(ans==a+b) { printf("Very good!"); is_correct=1; break; } else { attempts--; if(attempts>0) printf("Wrong!再试一次!\n&quot;); } } if(!is_correct) printf("\n正确答案是:%d\n&quot;, a+b); return 0; } void do_add(){ circulate_count(1);//现在是加法模式 } int do_singlesub() { int a=rand()%20+1; int b=rand()%20+1; int ans; int attempts=3; int is_correct=0; while(attempts>0){ printf("\n %d-%d=?(还有%d次机会)",a,b,attempts); scanf("%d",&ans); if(ans==a-b) { printf("Very good!"); is_correct=1; break; } else { attempts--; if(attempts>0) printf("Wrong!再试一次!\n&quot;); } } if(!is_correct) printf("\n正确答案是:%d\n&quot;, a-b); return 0; } void do_sub() { circulate_count(2); } int do_singlemul() { int a=rand()%20+1; int b=rand()%20+1; int ans; int attempts=3; int is_correct=0; while(attempts>0){ printf("\n %d*%d=?(还有%d次机会)",a,b,attempts); scanf("%d",&ans); if(ans==a*b) { printf("Very good!"); is_correct=1; break; } else { attempts--; if(attempts>0) printf("Wrong!再试一次!\n&quot;); } } if(!is_correct) printf("\n正确答案是:%d\n&quot;, a*b); return 0; } void do_mul() { circulate_count(3); } int do_singlediv() { int result=rand()%9+2; int b=rand()%10+1; int a=b*result; int ans; int attempts=3; int is_correct=0; while(attempts>0){ printf("\n %d/%d=?(还有%d次机会)",a,b,attempts); scanf("%d",&ans); if(ans==a/b) { printf("Very good!"); is_correct=1; break; } else { attempts--; if(attempts>0) printf("Wrong!再试一次!\n&quot;); } } if(!is_correct) printf("\n正确答案是:%d\n&quot;, a/b); return 0; } void do_div() { circulate_count(4); } int do_singlemixed() { char ops[]={'+','-','*','/'}; int a=rand()%20+1; int b=rand()%20+1; int c=rand()%20+1; char op1=ops[rand()%4]; char op2=ops[rand()%4]; float correct=0; if ( (op1=='+'||op1=='-')&& (op2=='*'||op2=='/')) { float second=(op2=='*')?b*c:(float)b/c; correct =(op1 =='+')?a+second:a-second; } else { float first; switch(op1) { case '+': first = a + b; break; case '-': first = a - b; break; case '*': first = a * b; break; case '/': first = (float)a / b; break; } switch(op2) { case '+': correct = first + c; break; case '-': correct = first - c; break; case '*': correct = first * c; break; case '/': correct = first / c; break; } } float ans; printf("%d %c %d %c %d=?",a,op1,b,op2,c); printf("\n(结果保留两位小数)"); scanf("%f",&ans); if(fabs(ans-correct)<0.01) { printf("Very good!"); return 1; } else { printf("Wrong!"); return 0; } } void do_mixed() { circulate_count(5); } 在这个基础上压缩一下更加简洁,并且希望混合运算也能给出三次运算机会
最新发布
11-16
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值