投入就放过 发表于 2022-2-9 21:51:09

C语言第十五课 凯撒密码

#include <stdio.h>

int main()
{
      int ch;

      printf("请输入明文:");

      while ((ch = getchar()) != '\n')
      {
                if (ch >= 'a' && ch <= 'z')
                {
                        putchar('a' + (ch - 'a' + 3) % 26);   //这里取余是为了把字符转化成数字吗?还是说是其他意义?
                        continue;
                }

                if (ch >= 'A' && ch <= 'Z')
                {
                        putchar('A' + (ch - 'A' + 3) % 26);
                        continue;
                }

                putchar(ch);
      }

      putchar('\n');

      return 0;
}

isdkz 发表于 2022-2-10 00:48:53

本帖最后由 isdkz 于 2022-2-10 00:52 编辑

取余是为了让字母偏移后还是字母

(就像钟表一样,不管指针再怎么偏移都不会超出钟表的范围),

因为有26个字母,所以模26

jackz007 发表于 2022-2-10 02:10:10

本帖最后由 jackz007 于 2022-2-10 02:22 编辑

        在计算机内部,每个字符都是通过编码来进行表示的,这个编码叫 ASCII 码。26 个英文字母的编码是按字母顺序以升序排列的,'a' - 'z' 对应的 ASCII 编码为 97 - 122,所以,可以说,字符就是数字。
    当 ch 是一个英文字母时,ch - 'a' 的数值为 0 - 25,而 ch - 'a' + 3 的数值是 3 - 28,显然,数值范围被整体向后平移了 3 个字符的距离,从而超出了英文字母的正常编码范围。我们希望的效果是把 26 - 28 平移填补到 0 - 2 的位置上,使得 ch - 'a' + 3 的数值依然保持 0 - 25,那么,如何才能做到呢?必须是取余啊!通过将 ch - 'a' + 3 对 26 进行取余操作就可以把 ch - 'a' + 3 的数值范围从 3 - 28 完美地调整回 0 - 25,这样,只要 ch 是一个英文字母,那么,'a' + (ch - 'a' + 3) % 26 就必然也是一个英文字母。
    例如,ch = 'k'(ASCII 编码 107),那么,'a' + (ch - 'a' + 3) % 26 = 97 + (107 - 97 + 3) % 26 = 97 + 13 % 26 = 97 + 13 = 110 = 'n',所以,输入字母 'k' 得到的密文字母是 'n';
    例如,ch = 'y'(ASCII 编码 121),那么,'a' + (ch - 'a' + 3) % 26 = 97 + (121 - 97 + 3) % 26 = 97 + 27 % 26 = 97 +1 =98 = 'b',所以,输入字母 'y' 得到的密文字母是 'b'。
页: [1]
查看完整版本: C语言第十五课 凯撒密码