我对在C中的角色执行的数学运算感到困惑。这是为了实现一个基本的密码。我正在使用存储在命令行参数argv。
中的字符串for (int i = 0, n = strlen(p), m = strlen(argv[1]); i < n; i++)
{
if ((p[i] >= 'A' && p[i] <= 'Z') || (p[i] >= 'a' && p[i] <= 'z'))
{
if (argv[1][i % m] >= 'A' && argv[1][i % m] <= 'Z')
{
printf("%c", ((p[i] - 'A') + ((argv[1][i % m]) - 'A')) % 26);
}
else if (argv[1][i % m] >= 'a' && argv[1][i % m] <= 'z')
{
printf("%c", ((p[i] - 'a') + ((argv[1][i % m]) - 'a')) % 26);
}
}
else
{
printf("%c", p[i]);
}
我的困惑在于“printf”行。它们不是按照书面印刷的,我不知道为什么。我做了一些测试,发现我的代码打印正常,如果我删除 - 'a'和%26,它只是看起来像:
printf("%c", p[i] + argv[1][i % m]);
但是,我不知道为什么会这样。在我看来,我所要做的应该与教授给出的例子没什么不同:
string s = get_string();
if (s != NULL)
{
for (int i = 0, n = strlen(s); i < n; i++)
{
if (s[i] >= 'a' && s[i] <= 'z')
{
printf("%c", s[i] - ('a' - 'A'));
}
else
{
printf("%c", s[i]);
}
}
特别是,行:
printf("%c", s[i] - ('a' - 'A'));
非常感谢任何指导!
答案 0 :(得分:3)
你是对的,你可以简化你的代码。
在C中,'a'
之类的内容是int
类型。 (与流行的看法相反,它们是不 char
类型,只是C标准保证它们可以被分配到char
类型而没有任何溢出的危险。)单引号表示法用于避免C不强制要求特定字符编码的事实。也就是说,您不应该关心'a'
等代表的数字。如果你关心,那么严格来说你的代码不是便携式的。
是的,表单(a - b) - (c - b)
的表达式简化为a - c
。
答案 1 :(得分:3)
printf("%c", ((p[i] - 'a') + ((argv[1][i % m]) - 'a')) % 26);
从芭丝谢芭被盗:
所以是的,你的形式(a - b) - (c - b)的表达式简化为a - c。
那么,(a - b)+(c - b)然后得到+ c - 2 * b ......
所以你先得到:
printf("%c", (p[i] + argv[1][i % m] - 2*'a') % 26);
// ^ yet left...
下一个点是%26 - 它将计算从0到26的值 - 这些都是您可能不希望看到的控制字符...
请注意&#39; a&#39;数值为97且A&#39; 65(ASCII,至少......)。因此,您有兴趣将此值重新添加到结果中:
printf("%c", (p[i] + argv[1][i % m] - 2*'a') % 26 + 'a');
// ^ (or 'A' in the upper case case)