【问题标题】:Changing a variable in a function has no effect更改函数中的变量无效
【发布时间】:2012-10-06 00:37:46
【问题描述】:
unsigned char xor4(unsigned char c1, unsigned char c2){
    int i = 0;
    while(i < 8){
        if((getBit(c1, i) ^ getBit(c2, i)))
             setBit(c1,i);
        else clearBit(c1, i);
        i+=2;
    }

    return c1;
}

上面的代码应该是一个非常简单的函数,它根据与第二个字符中的每隔一个位进行异或的结果来设置一个字符中的每隔一个位。出于某种原因,这根本行不通。该程序似乎只是忽略了我的 while 循环并返回原始函数。

哦,这是我的 getBit、setBit 和 clearBit 函数。

unsigned char getBit(unsigned char c, int n){
  return (c & 1<<n) >> n;
}

unsigned char clearBit(unsigned char c, int n){
  c = c & (~(1<<n));
}

unsigned char setBit(unsigned char c, int n){
  `c = c | (1<<n);
}

【问题讨论】:

  • return c1 ^ c2; 将是一种更有效的方法。
  • 一个重要的问题:究竟是什么让您认为 while 循环 不起作用?您如何验证这些循环是否确实有效?
  • @KarolyHorvath 的观点可能有点过于微妙。 OP 错误地认为 while 循环没有执行。一些明智的 printfs 会验证它正在执行,但 setbit 和 clearbit 调用没有改变 c1。

标签: c loops while-loop


【解决方案1】:

当您调用setBitclearBit 时,您会将c1副本 传递给这些函数。因此xor4c1 的值根本没有改变。

替换

 if((getBit(c1,i)^getBit(c2,i))) setBit(c1,i);
 else clearBit(c1,i);

直接设置或清除操作,

 if((getBit(c1,i)^getBit(c2,i))) c1 |= (1 << i);
 else c1 &= ~(1 << i);

(但是,as was pointed out,只需将函数替换为简单的c1 ^ c2 会更有效。)

【讨论】:

  • 谢谢。我不能使用直接设置和清除操作,因为它是一个分配,我们应该自己编写设置和清除操作作为分配的一部分。我也做了这些功能供参考
【解决方案2】:

您没有发布您的 setbit 和 clearbit 函数,但无论它们做什么,都无法更改调用函数中的 c1。您需要传递 c1 的地址或返回 c1 的新值。或者您可以只使用 C 位运算符。而你的整个操作就相当于c1 ^= c2(假设一个char有8位)。

编辑:鉴于您的编辑,只需将函数的返回值分配给 c1 ...并修复您的 setbit 和 clear bit 函数...它们不返回值,并且如果您在您的编译器它会告诉你。我做了一些风格上的改变:

/* your getbit works but is needlessly complex */
unsigned char getBit(unsigned char c, int n){
    return (c >> n) & 1; 

unsigned char clearBit(unsigned char c, int n){
    return c & ~(1 << n);
}

unsigned char setBit(unsigned char c, int n){
    return c | (1 << n);
} 

unsigned char xor4(unsigned char c1, unsigned char c2){
    for( int i = 0; i < 8; i += 2 )
        c1 = ( getBit(c1, i) ^ getBit(c2, i)
               ? setBit(c1, i);
               : clearBit(c1, i) );

    return c1;
}

这里有一个更快的解决方案:

unsigned char xor4(unsigned char c1, unsigned char c2){
    return (c1 & 0xAA) | ((c1 ^ c2) & 0x55);
}

更快:

unsigned char xor4(unsigned char c1, unsigned char c2){
    return (c2 & 0x55) ^ c1;
}

【讨论】:

  • 谢谢。我添加了设置和清除位功能。我还编辑了代码,因为那里有一个错字。我不能使用 c1 ^= c2 的原因是我必须改变每一位而不是每一位
  • 非常感谢。我想我一直在使用 Java 思维方式进行 C 编程
  • @OladunniAbiodun 查看我的编辑。这在 Java 中也应该可以工作(只需稍作语法调整),并且您的代码将因同样的原因而失败......产生值的函数必须返回这些值,并且调用者必须将它们分配到某个地方才能使用它们。
  • 谢谢。 Java 的想法是在某种意义上,我假设我正在使用我直接访问的对象,而忘记了我正在使用原始变量的副本。哦,但是是的,我看到我是如何完全延迟不将我的 setBit 和 clearBit 的返回值存储在实际变量中的。再仔细看,我原来的 set 和 clear 实际上并没有 return 语句,这可能会使一切变得更糟。我非常喜欢你的最后两个解决方案,但我认为这不是我所要求的,所以我想我会选择第一个。非常感谢您的帮助。
  • @OladunniAbiodun C 和 Java 共享所有参数都按值传递的属性。 (嗯,我上次使用 Java 是很久以前的事了。)是的,我在编辑中修复了你的 setbit/clearbit。
猜你喜欢
  • 2019-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-05
相关资源
最近更新 更多