位操作不是C语言的强项,汇编语言在这方面要好很多。如果涉及大量位操作,往往采用C语言和汇编语言混合编程的方法。
1.单纯采用C语言进行位截取操作时,我们可以将截取的各个二进制位所在的字节读取出来,然后让所取的二进制位依次左移到新单元的首位。由于左移可能会用到下一字节的前几位,我们需要进行一次或操作来合并两部分。
2.对某个或某些位的操作,我们可以将该单元与一个特定的数进行与运算,该数的特定位为1,其余位为0。比如取奇数位,我们可以将该字节与10101010进行与运算。将两个40位的数据各个字节都与10101010进行与运算后,再相互进行或运算,然后结果取反。逻辑运算部分你自己多看看书,多思考。(你的问题补充仍然不详细,两数据的偶数位如何处理?保留第一个的?)
我写了一个例子,用来截取内存区域中从第4位(下标始于0)开始的40位,将之存放在子函数的静态变量中,然后计算这40位中奇数位是“1”的个数,供你参考。
#include
#define N 576
unsigned char* get(unsigned char* array, int head, int num) /*从第head位开始,读取num个二进制位*/
/*该函数不开辟额外空间用于存储新数据,请将返回值指向的数组自行复制*/
{
static unsigned char here[N]; /*静态数组用于存放读取的各个二进制位*/
unsigned char* p, t;
int i,key,bak;
if(head+num>N || head<0 || num<=0) /*溢出判断*/
{
printf("Overflow!\n");
return NULL;
}
p=array+head/8; /*第一位所在字节*/
/*对非整字节数据的标记*/
key=head%8; /*第一位在其所属字节中的位置*/
bak=8-key; /*第一位在其所属字节中的右序位置*/
for(i=0;i
/*将各字节左移key位,其下一字节右移bak位,二者与运算即为结果*/
t=((*p)<
here[i]=t;
p++;
}
return here;
}
int fun(unsigned char* array, int num) /*统计奇数位“1”的个数*/
{
int i,key,end;
unsigned char t;
int res=0; /*统计结果*/
if(num>N || num<=0) /*溢出判断*/
{
printf("Overflow!\n");
return 0;
}
end=num/8; /*最后一位所处字节*/
for(i=0;i
/*与二进制的10000000进行与运算,判断第一位是否是“1”*/
if(*array&0x80) res++;
/*与二进制的00100000进行与运算,判断第三位是否是“1”*/
if(*array&0x20) res++;
/*与二进制的00001000进行与运算,判断第五位是否是“1”*/
if(*array&0x08) res++;
/*与二进制的00000010进行与运算,判断第七位是否是“1”*/
if(*array&0x02) res++;
array++;
}
/*对剩余的非完整字节数据的处理*/
key=num%8; /*最后一位在其所属字节中的位置*/
for(i=0,t=(unsigned char)0x80;i
{
if(*array&t) res++;
}
return res;
}
void main()
{
unsigned char array[N];
unsigned char* p;
int i,res;
for(i=0;i
p=get(array,4,40);
res=fun(p,40);
printf("%d\n",res);
}
1.如何从一段内存区域内(576个字节数据),每次取出固定个数的数据位分别进行不同的操作,比如第一次取出40位操作,第二次取出60位,第三次取出N位。。。
要实现这些操作,用那些位操作语句比较方便呢? 可否具体写个例子?
C语言无法实现,只能取自己进程段的内存,不能动别的,否则破坏操作系统啥的不太容易了?
2.对于上面取出的比如40位的数据,我要分别对它们的奇数位和偶数位进行一些不同的逻辑操作,怎样操作能把奇数位偶数位比较方便的分别操作,再把最终结果和到一起呢?
最好能用具体程序例子说明 谢谢了 就52分 全给您了
int x;//数据
int a,b;
a=x|0xAAAAAAAAAA;//偶数位
b=x|~0xAAAAAAAAAA;//奇数位