我正在做 CS50 的凯撒问题集,当我尝试移动大写字母时,使用 if (isupper(argument) == true)
来检查我想移动的字符是否为大写,它没有用,它认为大写字母是' t,实际上是大写。当我将它切换到 if (isupper(argument))
时,程序正确地转换了大写字母。
这两种格式有什么区别吗?
这是我使用的代码(我指的是 for 循环中的代码):
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
//Check wether there is only 1 command line argument
if (argc == 2)
{
//Check if there is any character that's not a digit
for (int i = 0; i < strlen(argv[1]); i++)
{
if (isdigit(argv[1][i]) == false)
{
printf("Usage: ./caesar key\n");
return 1;
}
}
}
else
{
printf("Usage: ./caesar key\n");
return 1;
}
//Convert key to an int
int key = atoi(argv[1]);
//Prompt plaintext
string plaintext = get_string("plaintext: ");
string ciphertext = plaintext;
//Shift ciphertext's characters by the amount of "key"
for (int i = 0; i < strlen(plaintext); i++)
{
//If it isn't a letter, do nothing
if (isalpha(plaintext[i]) == false)
{
ciphertext[i] = plaintext[i];
}
else
{
//If it's uppercase
if (isupper(plaintext[i]) == true)
{
//Convert ASCII to alphabetical index
plaintext[i] -= 'A';
//Shift alphabetical index
ciphertext[i] = (plaintext[i] + key) % 26;
//Convert alphabetical index to ASCII
ciphertext[i] += 'A';
}
//If it's lowercase
else if (islower(plaintext[i]))
{
//Convert ASCII to alphabetical index
plaintext[i] -= 'a';
//Shift alphabetical index
ciphertext[i] = (plaintext[i] + key) % 26;
//Convert alphabetical index to ASCII
ciphertext[i] += 'a';
}
}
}
//Print ciphertext
printf("ciphertext: %s\n", ciphertext);
}
答案 0 :(得分:6)
int isupper(int) 不返回布尔值(0 或 1 值)。如果 arg 为大写,则返回非零整数。
这两种情况的区别在于,一种将返回值与1进行比较,另一种将返回值与非零进行比较。
答案 1 :(得分:5)
当你有一些你认为是真的/假的东西时,永远不要写
public void initChannel(SocketChannel ch);
或
if(thing == true)
随便写
if(thing == false)
或
if(thing)
事实证明 if(!thing)
和 isupper()
以及 islower()
中的其余 isxxx 函数为 false/true 返回零/非零,但不一定 0/1。如果 <ctype.h>
返回,例如 4,那么 isupper('A')
将按您的预期工作,但 if(isupper(argument))
将始终失败。
答案 2 :(得分:0)
将真值(布尔表达式)与真值常量进行比较是不好的方式
if (isdigit(argv[1][i]) == false) // Bad style
if (!isdigit(argv[1][i])) // Better
if (isupper(argument) == true) // Bad style
if (isupper(argument)) // Better
在 isupper
的情况下,有一个隐藏的错误。为了成为“真”,C 中的非零就足够了。但是 true
在 C 中被定义为 1。
==/!= true/false
还显示二级布尔值,您也可以这样做 (X == true) == true
。冗余和隐藏作为一等公民的原始状态。它表明缺少一点编程知识(虽然不严重)。
答案 3 :(得分:0)
来自 C 标准(7.4.1 字符分类函数)
<块引用>1 本小节中的函数返回非零(真)如果和 仅当参数 c 的值符合 功能描述。
也就是说,在 C 中,条件中使用的任何非零值都被视为逻辑真。它与标头 true
中定义的常量 <stdbool.h>
不同。也就是说,任何函数 isdigit
、isalpha
或 isupper
都可以返回任何非零值作为真值。但这并不意味着该函数将准确返回标头 1
中定义的常量 <stdbool.h>
作为宏 true
。因此,例如这个 if 语句
if (isupper(plaintext[i]) == true)
你必须要么写
if (isupper(plaintext[i]) )
或者例如
if (isupper(plaintext[i]) != false)
因为常量 false
等价于值 0
。