将 char 与 int 相加的 C 程序

C program that sums a char with int

我有一个给定的练习,要我从字母中找到 K 位置的大写字母,在这种情况下,名为 C 的 char 变量。范围是从 A 到 Z 的大写字母。

例如,如果输入是 B 3,输出应该是 E。对于这个特定的输入,它很简单,您只需对值求和即可得到答案,但是例如,如果我们超出范围会怎样。这是一个示例 F 100 程序应该输出 B 因为如果值大于 Z 则程序从 A 开始。

如果有一些混淆,我会尝试更多地解释这里是一些测试用例和我的代码,只有在我们不跨越范围时才有效。

Input    Output
B 3        E
X 12345    S
F 100      B
T 0        T
#include <stdio.h>

int main(){
    int K;
    char C,rez;
    scanf("%c %d",&C,&K);

    int ch;
    for(ch = 'A';ch <= 'Z';ch++){
           if(C>='A' && C<='Z'){
               rez = C+K;
           }
    }

    printf("%c",rez);
    return 0;
}

将字母 [A-Z] 视为 base 26,其中 A 为 0,B 为 1,Z 为 25。

当我们对字母(以 26 为基数)和偏移量求和时,它只是我们感兴趣的最低有效基数 26 位,因此使用 % 找到最低有效基数 26 位,就像一个使用 % 10 找到最不重要的 decimal 数字。

scanf(" %c %d",&C,&K);
//     ^ space added to consume any white-space

if (C >= 'A' && C <= 'Z') {
  int base26 = C - 'A';
  base26 = base26 + K;
  base26 %= 26;
  int output = base26 + 'A';
  printf("%c %-8d %c\n", C, K, output);
}

对于负偏移量,我们需要做更多的工作,因为 % 不是 mod 运算符,而是 余数。这个 differs 带有一些负操作数。

  base26 %= 26;
  if (base < 0) base26 += 26; // add
  int output = base26 + 'A';

迂腐地,C + K 可能会溢出极端的 K 值。考虑到这一点,在添加之前减少 K

  // base26 = C + K;
  base26 = C + K%26;

我们可以偷偷摸摸地加上 26 以确保总和不为负。

if (C >= 'A' && C <= 'Z') {
  int base26 = C - 'A';
  base26 = base26 + K%26 + 26; // base26 >= 0, even when K < 0
  base26 %= 26; // base26 >= 0 and < 26
  int output = base26 + 'A';
  printf("%c %-8d %c\n", C, K, output);
}

...或者做一个复杂的单行

  printf("%c %-8d %c\n", C, K, (C - 'A' + K%26 + 26)%26  + 'A');

这可以通过使用 2 个概念来完成。

  1. ASCII 值
  2. 模运算符 (%)

在 C 中,每个字符都有一个 ASCII 值。基本上它是从 0-127。 字符 'A' 的值为 65 字符 'B' 的值为 66 (65 + 1) 等等... 直到 Z 为 65 + 25 = 90

我想强调的第二个数学概念是模运算,如果您总是想将数字映射到特定范围,则可以使用模运算符。 模数是一个数字除以另一个数字后得到的提醒。 在我们的例子中,我们有 26 个字母表,所以我们总能得到 0 到 25

之间的数字

对于你举的例子 100% 26 = 22 但是你也要考虑出发点。

所以,我们总是用 'A' 的值减去初始字母表,即 65,这样 'A' 映射到 0,'Z' 映射到 25

所以,如果我们从 'F' 开始,需要去 100 个地方..

  1. 从 'F' 值中减去 'A' 值。字符的行为类似于数字,因此您实际上可以将 'F' - 'A' 存储为整数

在这种情况下 'F' - 'A' = 5

  1. 接下来我们给它加上偏移量。 5 + 100 = 105

  2. 然后我们用26取模 105 % 26 = 1

  3. 最后把'A'的值加回结果 'A' + 1 = 'B'

大功告成

使用取模运算符 26 得到输入数字的余数。如果输入字符和余数的总和小于或等于 Z 那么它的答案否则再次找到总和的余数 26 这将是答案(注意偏移量因为 ASCII 十进制值字母 A 是 65).

大致的实施将是:

#include <stdio.h>

int main(){
    int K;
    char C, rez;
    scanf("%c %d",&C,&K);
    // Validate the user input

    int ch;

    int rem = K % 26;

    if ((rem + C) - 'A' < 26) {
        rez = rem + C;
    } else {
        rez = ((rem + C - 'A') % 26) + 'A';
    }
    
    printf("%c\n",rez);

    return 0;
}

请注意,我知道实施方面还有改进的余地。但这只是为了让 OP 了解如何完成它。

输出:

# ./a.out
B 3
E
# ./a.out
X 12345
S
# ./a.out
F 100
B
# ./a.out
T 0
T