C 函数,该函数只返回一个字的偶数位

C 函数,该函数只返回一个字的偶数位,c,bit-manipulation,C,Bit Manipulation,我正在尝试创建一个函数,它将16位作为参数,只返回其中的偶数位(甚至作为索引),基本上应该返回8位 例如,如果我们有:yx-yx-yx-yx-yx 函数应返回:xxxx xxxx 我很迷茫,但我一开始是: unsigned char function(unsigned short int p){ unsigned char q=0; for(int i=15;i>=0;i--){ if(i%2==0){ //now we have somehow

我正在尝试创建一个函数,它将16位作为参数,只返回其中的偶数位(甚至作为索引),基本上应该返回8位

例如,如果我们有:yx-yx-yx-yx-yx

函数应返回:xxxx xxxx

我很迷茫,但我一开始是:

unsigned char function(unsigned short int p){
   unsigned char q=0;
   for(int i=15;i>=0;i--){
      if(i%2==0){
         //now we have somehow to take that bit because it has an even index
      }
   }
return q;
}

你能帮我完成这个吗?

使用一些位运算:

charf(短int p){
char ans=0;
对于(int i=14;i>=0;i-=2){

ans |=((p>>i)&1)使用一些位运算:

charf(短int p){
char ans=0;
对于(int i=14;i>=0;i-=2){
ans |=((p>>i)&1)另一种解决方案(我也是初学者)

#包括
int main()
{
uint16_t i=21;/*之所以选择此样本,是因为它不是完整的掩码*/
uint8_t k=0;
int l=0;
对于(int j=0;j<16;j+=2){
如果(i&(1另一种解决方案)(我也是初学者)

#包括
int main()
{
uint16_t i=21;/*之所以选择此样本,是因为它不是完整的掩码*/
uint8_t k=0;
int l=0;
对于(int j=0;j<16;j+=2){

如果(i&(1有多种方法可以写下这种算法。在这里,我将使用最容易理解的方法。但是首先,让我们更改函数的签名以使用正确的类型:

#include <stdint.h>

uint8_t function(uint16_t p);
将给我们该位。现在我们要将该位存储在
q
中的正确位置。将有一些索引
i
。因此:

q = q | (right_most_bit << i);
或更短:

p >>= 2;
这就给我们留下了一个创建循环的问题,这样我们的
i
在每次迭代中增加1。循环应该在
p
为0时结束,因为那时我们知道将没有更多的位可提取。这有一个好处,循环将只在所需的最小迭代量下运行。所以

for (unsigned i = 0; p != 0; i++)
我们把这些放在一起:

for (unsigned i = 0; p != 0; i++) {
    uint8_t right_most_bit = p & 1;
    q |= (right_most_bit << i);
    p >>= 2;
}
uint8_t function(uint16_t p)
{
    uint8_t q = 0;

    for (unsigned i = 0; p != 0; i++, p >>= 2) {
        q |= ((p & 1) << i);
    }
    return q;
}
for(无符号i=0;p!=0;i++){
uint8\u t right\u most\u bit=p&1;
q |=(最右位>=2;
}
当然,您可以进一步简化:

for (unsigned i = 0; p != 0; i++, p >>= 2) {
    q |= ((p & 1) << i);
}
for(无符号i=0;p!=0;i++,p>>=2){
q |=((p&1)>=2){

q |=((p&1)写这种算法有多种方法。在这里,我将使用最容易理解的方法。但首先,让我们更改函数的签名以使用正确的类型:

#include <stdint.h>

uint8_t function(uint16_t p);
将给我们该位。现在我们要将该位存储在
q
中的正确位置。将有一些索引
i
。因此:

q = q | (right_most_bit << i);
或更短:

p >>= 2;
这就给我们留下了一个创建循环的问题,这样我们的
i
在每次迭代中增加1。循环应该在
p
为0时结束,因为那时我们知道将没有更多的位可提取。这有一个好处,循环将只在所需的最小迭代量下运行。所以

for (unsigned i = 0; p != 0; i++)
我们把这些放在一起:

for (unsigned i = 0; p != 0; i++) {
    uint8_t right_most_bit = p & 1;
    q |= (right_most_bit << i);
    p >>= 2;
}
uint8_t function(uint16_t p)
{
    uint8_t q = 0;

    for (unsigned i = 0; p != 0; i++, p >>= 2) {
        q |= ((p & 1) << i);
    }
    return q;
}
for(无符号i=0;p!=0;i++){
uint8\u t right\u most\u bit=p&1;
q |=(最右位>=2;
}
当然,您可以进一步简化:

for (unsigned i = 0; p != 0; i++, p >>= 2) {
    q |= ((p & 1) << i);
}
for(无符号i=0;p!=0;i++,p>>=2){
q |=((p&1)>=2){
q |=((p&1)
#包括
uint8_t foo(uint16_t p)
{
uint16_t tmp;
uint8_t面罩;
uint8_t结果;
结果=0;
对于(int i=0;i<8;i++){
tmp=p>>i;
掩码=1
#包括
uint8_t foo(uint16_t p)
{
uint16_t tmp;
uint8_t面罩;
uint8_t结果;
结果=0;
对于(int i=0;i<8;i++){
tmp=p>>i;


mask=1如果你知道索引,你知道如何从整数中提取一个位吗?试着写出两个表达式:一个从一个数字中提取索引
i
处的位,另一个将位
i
从一个数字复制到另一个数字。你应该在C@Zacky没有任何特殊资源。对于操作员ors,维基百科没问题。如果我是你,我会使用
uint16\u t
而不是
无符号短整数
。它保证了16位。如果你知道索引,你知道如何从整数中提取一位吗?试着写出两个表达式:一个从数字中提取索引
I
处的位,另一个是at将位
i
从一个数字复制到另一个数字。您应该阅读C@Zacky没有任何特殊资源。对于操作员来说,维基百科是可以的。如果我是你,我会使用
uint16\u t
而不是
unsigned short int
。它保证16位s14是神奇的。你也许应该写它作为
16-2
,这样就更清楚了为什么它永远不会对有符号变量进行移位!而且,C99之前的类型对于移位来说不是很好。一个
short int
有多长?另外,
char
应该只用于字符。对于任何其他目的,你应该使用
有符号字符
无符号字符以避免问题。更好的
(u)int8\t
除了特殊情况(别名).14是神奇的。你也许应该把它写成
16-2
,这样就更清楚为什么它永远不会对有符号变量进行移位了!而且,C99之前的类型对于移位来说不是很好。一个
short int int
有多长?另外,
char
应该只用于字符。对于任何其他用途,你应该使用
signed char
无符号char
以避免问题。除了特殊情况(别名)之外,更好的
(u)int8\t
。非常感谢!这对我很有用。//一个问题:这行不是应该是:q |=(是的,@Zacky他们也这么做。但是,我同意在这种情况下,
更有意义。@Zacky我使用了
+
,因为我认为它更容易理解。我现在把它改为
,因为它似乎有相反的效果,并且使它更混乱。@Zacky顺便说一句,
+
的效果更好。@Zackyse算法仅为e