如何在C++4位加法器的全加器函数中正确操作carry变量?
4位加法器中正确处理进位的方法
你用全局变量carry传递进位的写法确实存在不少问题:
- 全局状态会导致函数不可重入,比如多次调用
rippleAdder()时,上一次的进位残留会直接影响下一次计算结果 - 线程不安全,多线程环境下调用会出现竞态条件
- 代码耦合度高,
fullAdder的行为完全依赖外部全局变量,可读性和可维护性差 - 原代码里的
carry没有初始化,默认是未定义的随机值,会直接导致计算错误
下面是两种更合理的实现方式:
方法一:使用引用参数传递进位
把carry作为引用参数传给fullAdder,既能让函数修改进位值,又避免了全局变量的问题,同时必须记得初始化初始进位为0:
#include <iostream> using namespace std; bool inputs[8] = {0,0,0,1,0,0,0,1}; bool answer[4]; short fullAdder(bool val1, bool val2, bool& carry) { short sum = val1 + val2 + carry; switch (sum) { case 0: carry = 0; return 0; case 1: carry = 0; return 1; case 2: carry = 1; return 0; case 3: carry = 1; return 1; default: return 0; } } void rippleAdder() { bool carry = 0; // 初始化初始进位为0 answer[3] = fullAdder(inputs[3], inputs[7], carry); answer[2] = fullAdder(inputs[2], inputs[6], carry); answer[1] = fullAdder(inputs[1], inputs[5], carry); answer[0] = fullAdder(inputs[0], inputs[4], carry); cout << answer[0] << answer[1] << answer[2] << answer[3] << endl; // 如需输出最终进位,可在此打印carry } int main() { rippleAdder(); }
方法二:返回包含和与进位的结构体
让fullAdder返回一个包含计算结果和新进位的对象,这样函数完全没有副作用,逻辑更清晰:
#include <iostream> using namespace std; bool inputs[8] = {0,0,0,1,0,0,0,1}; bool answer[4]; // 用结构体存储全加器的结果与进位 struct FullAdderResult { bool sum; bool carryOut; }; FullAdderResult fullAdder(bool val1, bool val2, bool carryIn) { short sum = val1 + val2 + carryIn; FullAdderResult res; switch (sum) { case 0: res.sum = 0; res.carryOut = 0; break; case 1: res.sum = 1; res.carryOut = 0; break; case 2: res.sum = 0; res.carryOut = 1; break; case 3: res.sum = 1; res.carryOut = 1; break; default: res.sum = 0; res.carryOut = 0; } return res; } void rippleAdder() { bool carry = 0; auto res3 = fullAdder(inputs[3], inputs[7], carry); answer[3] = res3.sum; carry = res3.carryOut; auto res2 = fullAdder(inputs[2], inputs[6], carry); answer[2] = res2.sum; carry = res2.carryOut; auto res1 = fullAdder(inputs[1], inputs[5], carry); answer[1] = res1.sum; carry = res1.carryOut; auto res0 = fullAdder(inputs[0], inputs[4], carry); answer[0] = res0.sum; carry = res0.carryOut; cout << answer[0] << answer[1] << answer[2] << answer[3] << endl; } int main() { rippleAdder(); }
额外补充:原代码中answer的赋值是从高位到低位,输出时却是低位在前的顺序,如果需要高位在前的输出格式,调整cout的顺序即可。
内容的提问来源于stack exchange,提问作者Rekcut23
相关产品推荐
相关产品推荐

