C/C++一些比较有意思的算法
与运算
int x=9999;
int count = 0;
while(x)
{
count++;
x=x&(x-1);
}
printf("%d",count);
输出结果是8;
将9999化成二进制:9999/2=4999…1;
4999/2=2499…1
……
最后反过来写得到:10 0111 0000 1111;
而x-1即是 9998 :10 0111 0000 1110;
与一下就成了 :10 0111 0000 1110
即把原来的1变成0;一次下去经过八次变成0;
编程风格
if('A'==a){}写法比if(a=='A'){}好,因为如果把‘==’写成‘=’会报错,常量不准许赋值。
运算符
#include <iostream>
using namespace std;
int main()
{
unsigned char a=0xA5;
unsigned char b=~a>>4+1;
printf("b=%d\n",b);
return 0;
}
因为~的优先级别高于>>,所以是先对a取反,即1010 0101----> 0101 1010 因为+的优先级别大于>>,所以是右移5位,得到:0000 0010 结果是2;
但是这确实错误的答案,在vs2008上运行的时候结果却是 250;原来这是16为寄存器,0xA5是:0000 0000 1010 0101;取反之后变成:1111 1111 0101 1010 右移5位后得到的是:0000 0111 1111 1010;由于unsigned char型只能表示低八位,这样既得到: 250;
算法
用一个表达式判断一个数X是不是2的N次方(2,4,8……),不可以用循环语句。
答案:!(X&(X-1))
int f(int x,int y)
{
return (x&y)+((x^y)>>1);
}
(729,271)=?
仔细看一下题目发现:x&y是取相同的位与,这个的结果是x和y相同位的一半,x^y是取不相同的位与,又移一位相当除以2,这个函数的功能就是取两个书的平均值。
有两个变量a和b,不用if,?:,switch或其他判断语句,找出其中比较大的那个。
答案:
int max = ((a+b)+abs(a-b))/2
如何将a和b两个数的值交换,并且不使用任何中间变量。
方案一:
a=a+b;
b=a-b;
a=a-b;
方案二:
a=a^b;
b=a^b;
a=a^b;
异或运算法则:
a^a=0;
a^b=b^a;
a^b^c=a^(b^c)=(a^b^c);
d=a^b^c可得:a=d^b^c;
a^b^c=b;
字节:
#include <stdio.h>
void main()
{
int a,b,c,d,e,f,g;
char str1[100];
int str2[100];
a=sizeof(int);//int型是4个字节
b=sizeof(char);//char 1个字节
c=sizeof(1);// 4个字节
d=sizeof('c');//一个字节
e=sizeof("Hello");//每个字母一个字节 加上后面隐含的'\0',共6个字节
f=sizeof(str1);//100个字节
g=sizeof(str2);//定义了100个int型 共400个字节
printf("%d,%d,%d,%d,%d,%d,%d\n",a,b,c,d,e,f,g);
}
*/
/*
#include <stdio.h>
void main()
{
int a=sizeof("我们");//汉字是两个字节
printf("%d",a);
}
*/
补充:软件开发 , C++ ,