((c - 65 + k) % 26) + 65)
works, but is non portable and unnecessarily obfuscated.
65
is the ASCII code for 'A'
the character constant representing the letter A
. c - 65
or better c - 'A'
evaluates to the distance of the uppercase letter stored in c
from A
, hence 1
for the letter B
.
Adding k
operates a shift in the alphabet, but can produce offsets greater than 25, hence the modulo operation to compute the remainder of the division by 26
. (c - 65 + k) % 26
gives the offset if the encoded letter.
Adding 65
or more appropriately 'A'
converts the offset back to an uppercase letter.
This expression makes the silent assumption that all uppercase letters are consecutive in the execution character set, which is true for ASCII, but not for older character sets such as EBCDIC
.
Note also that the above expressions only work for positive values of k
. If k
is negative, the result of (c - 'a' + k) % 26 + 'a'
may be negative too, hence k
should be changed to a positive value first with this code:
k = k % 26;
if (k < 0)
k = k + 26;
Here is a more readable alternative:
char encode_letter(char c, int k) {
k = k % 26;
if (k < 0)
k = k + 26;
if (c >= 'A' && c <= 'Z')
return (c - 'A' + k) % 26 + 'A';
else
if (c >= 'a' && c <= 'a')
return (c - 'a' + k) % 26 + 'a';
else
return c;
}