"if (isupper(argument) == true)" 和“if (isupper(argument))”有什么区别?注意:参数是我程序中的任何字符
What's the difference between "if (isupper(argument) == true)" and " if (isupper(argument))"? Note: argument is any char in my program
我在做 CS50 的凯撒问题集,当我试图移动大写字母时,使用 if (isupper(argument) == true)
检查我想移动的字符是否是大写的,它没有用,它认为大写字母事实上,不是大写的。当我将它切换到 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);
}
int isupper(int) 不是 return 布尔值(0 或 1 值)。如果 arg 是大写的,它 return 是一个非零整数。
两种情况的区别在于,一种是将return值与1进行比较,另一种是将return值与非零值进行比较。
当你有一些你认为是true/false的东西时,永远不要写
if(thing == true)
或
if(thing == false)
随便写
if(thing)
或
if(!thing)
原来 isupper()
和 islower()
以及 <ctype.h>
return zero/nonzero 中的其余 isxxx 函数用于 false/true,但 不一定 0/1。如果 isupper('A')
returns,比方说,4,那么 if(isupper(argument))
会按你预期的那样工作,但 if(isupper(argument) == true)
总是会失败。
另见 question 9.2 in the C FAQ list。
将真值(布尔表达式)与真值常数进行比较是一种糟糕的风格
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
的情况下,有一个隐藏的 bug。为了成为“真”,在 C 中非零就足够了。但是true
在C中定义为1.
==/!= true/false
也显示二等布尔值,你也可以做 (X == true) == true
。冗余和隐藏作为一等公民的原始状态。它显示了编程知识的缺失(虽然不严重)。
来自C标准(7.4.1字符分类函数)
1 The functions in this subclause return nonzero (true) if and
only if the value of the argument c conforms to that in the
description of the function.
即在 C 中,条件中使用的任何 non-zero 值都被视为逻辑真。它与 header <stdbool.h>
中定义的常量 true
不同。即任何函数 isdigit
、isalpha
或 isupper
都可以 return 任何 non-zero 值作为真值。但并不意味着函数将return恰好1
定义在header<stdbool.h>
中的常量true
作为宏true
。因此,例如这个 if 语句
if (isupper(plaintext[i]) == true)
你必须写
if (isupper(plaintext[i]) )
或者例如
if (isupper(plaintext[i]) != false)
因为常量 false
等价于值 0
.
我在做 CS50 的凯撒问题集,当我试图移动大写字母时,使用 if (isupper(argument) == true)
检查我想移动的字符是否是大写的,它没有用,它认为大写字母事实上,不是大写的。当我将它切换到 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);
}
int isupper(int) 不是 return 布尔值(0 或 1 值)。如果 arg 是大写的,它 return 是一个非零整数。
两种情况的区别在于,一种是将return值与1进行比较,另一种是将return值与非零值进行比较。
当你有一些你认为是true/false的东西时,永远不要写
if(thing == true)
或
if(thing == false)
随便写
if(thing)
或
if(!thing)
原来 isupper()
和 islower()
以及 <ctype.h>
return zero/nonzero 中的其余 isxxx 函数用于 false/true,但 不一定 0/1。如果 isupper('A')
returns,比方说,4,那么 if(isupper(argument))
会按你预期的那样工作,但 if(isupper(argument) == true)
总是会失败。
另见 question 9.2 in the C FAQ list。
将真值(布尔表达式)与真值常数进行比较是一种糟糕的风格
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
的情况下,有一个隐藏的 bug。为了成为“真”,在 C 中非零就足够了。但是true
在C中定义为1.
==/!= true/false
也显示二等布尔值,你也可以做 (X == true) == true
。冗余和隐藏作为一等公民的原始状态。它显示了编程知识的缺失(虽然不严重)。
来自C标准(7.4.1字符分类函数)
1 The functions in this subclause return nonzero (true) if and only if the value of the argument c conforms to that in the description of the function.
即在 C 中,条件中使用的任何 non-zero 值都被视为逻辑真。它与 header <stdbool.h>
中定义的常量 true
不同。即任何函数 isdigit
、isalpha
或 isupper
都可以 return 任何 non-zero 值作为真值。但并不意味着函数将return恰好1
定义在header<stdbool.h>
中的常量true
作为宏true
。因此,例如这个 if 语句
if (isupper(plaintext[i]) == true)
你必须写
if (isupper(plaintext[i]) )
或者例如
if (isupper(plaintext[i]) != false)
因为常量 false
等价于值 0
.