CS50 Bulbs二进制程序故障排查:为何所有灯泡全亮?
CS50 Bulbs作业代码问题排查
我写了一段C语言代码,想把用户输入的字符串用灯泡emoji以二进制形式展示,但现在所有灯泡都显示点亮状态。我知道可以用取余法实现,但想搞懂当前代码哪里出了问题——明明逻辑是让字符值递减,却没达到预期效果。
我的代码如下:
#include <cs50.h> #include <stdio.h> #include <string.h> #include <math.h> const int BITS_IN_BYTE = 8; int main(void) { string text = get_string("Text to encrypt!: "); int bit; int count = 1; for (int i = 0, y = 7, n = strlen(text); i < n; i++) { int result = text[i]; while (result != 0 && y >= 0) { if (result > (2^y)) { bit = 1; print_bulb(bit); result = text[i] - (2^y); y--; } else { bit = 0; print_bulb(bit); y--; } printf("\n"); } } } void print_bulb(int bit) { if (bit == 0) { // Dark emoji printf("\U000026AB"); } else if (bit == 1) { // Light emoji printf("\U0001F7E1"); } }
问题拆解
致命错误:
^不是幂运算符
C语言里^是按位异或,不是你以为的幂运算。比如2^7算出来是9(二进制10异或111=1001),不是128。这导致你的判断条件result > (2^y)几乎永远为真,所以bit一直是1,灯泡全亮。
要算2的y次方,要么用1 << y(位运算,高效准确,比如1<<7就是128),要么用(int)pow(2, y)(需要math.h,注意转成int)。循环逻辑漏洞
y的初始化位置错了:你把y=7放在外层for循环的初始化里,处理完第一个字符后y会变成-1,后面的字符根本进不了while循环。应该把y=7移到for循环内部,每次处理新字符时重置y为7。- while循环条件错误:
result != 0 && y >=0会导致当result减到0时,剩下的低位0直接跳过不输出。比如字符'A'是65(二进制1000001),减到0后剩下的5个0就没了。应该改成只判断y >=0,确保每个字符都输出完整的8位。 result更新错误:你写的result = text[i] - (2^y)是用原字符的ASCII值去减,而不是用当前剩余的result值。应该改成result -= 对应的幂值,这样才能逐步递减剩余值。
输出格式错误
你把换行printf("\n");放在了while循环里,导致每个灯泡都单独占一行。正确的应该是每个字符的8个灯泡输出完后再换行,所以把换行移到while循环外面、for循环内部。
修正后的代码示例
#include <cs50.h> #include <stdio.h> #include <string.h> const int BITS_IN_BYTE = 8; void print_bulb(int bit); int main(void) { string text = get_string("Text to convert: "); for (int i = 0, n = strlen(text); i < n; i++) { int result = text[i]; // 每次处理新字符时重置y为7(最高位) for (int y = 7; y >= 0; y--) { int power = 1 << y; // 用位运算计算2^y if (result >= power) { print_bulb(1); result -= power; } else { print_bulb(0); } } printf("\n"); // 每个字符的8位输出完后换行 } } void print_bulb(int bit) { if (bit == 0) { printf("\U000026AB"); } else { printf("\U0001F7E1"); } }
内容的提问来源于stack exchange,提问作者Rae
相关产品推荐
相关产品推荐

