在C中 我想检查变量是否等于多个值,并且不完全分离也不知道如何编码。
if (str[i]=='u'||'o'||'i'||'e'||'a')
让我永远是真实的,我不明白为什么,我需要解释。
if (str[i]==('u'||'o'||'i'||'e'||'a'))
总是给我假,我不明白为什么,我需要解释。
谢谢。
答案 0 :(得分:2)
以下表达式始终返回true的原因:
if (str[i] == 'u'||'o'||'i'||'e'||'a')
是字符常量的值为true。因此,以上内容实际上是相同的:
if (str[i] == 'u'|| 1 || 1 || 1 || 1)
您打算做的是这个
if (str[i] == 'u' || str[i] == 'o' || str[i] == 'i' || str[i] == 'e' || str[i] == 'a')
请注意,每次比较都需要重复相等表达式。
答案 1 :(得分:2)
您需要:
d = [[0, 0, 192], [0, 0, 0, 0, 56]]
d = [[int(bool(x)) for x in l] for l in d]
print(d)
一个[[0, 0, 1], [0, 0, 0, 0, 1]]
:
import numpy as np
d = np.array([[0, 1, 2], [3, 0, 4], [5, 6, 0]])
d = np.where(d == 0, 0, 1)
print(d)
可能有更好的机会为您提供更好的代码(自从C的第一个版本以来,上述开关就被用于有效的词法化),而且很多人(包括我)也发现它更具可读性。 (如果您将案例放在{}复合语句中,很多人会发现它更具可读性,但是我正在经历一个阶段,我会尽可能地将它们排除在外。)
答案 2 :(得分:1)
不同的结果与运算符优先级有关。
x == y || z
与
相同(x == y) || z
与
不同x == (y || z)
您的表达式为'u'||'o'||'i'||'e'||'a'
,因此在我们的情况下,y
将为'u'
,而z
将为'o'||'i'||'e'||'a'
。 z
的计算结果为true,因为至少一个操作数(在本例中为所有操作数)非零。因此,第一行将等效于(str[i] == 'u') || 1
,该行当然总会求值为1,这是正确的。另一方面,str[i] == ('u' || 1)
与str[i] == 1
相同,因为'u' || 1
的计算结果为1。
在C语言中,没有很好的内置方法来完成这样的事情。您可以做的,很容易概括的是编写这样的自定义函数:
bool isMember(char e, char*s, size_t size)
{
for(size_t i; i<size; i++) {
if(s[i] == e)
return true;
}
return false;
}
上述功能很容易针对不同类型进行修改。但是在您的情况下,可以这样使用:
char characters[] = {'u','o','i','e','a'};
if (isMember(str[i], characters, sizeof(characters)) {
在处理char
时,有一些更简单的方法,但我选择此解决方案是因为它不仅限于char
。
答案 3 :(得分:0)
使用||
或(str[i]=='u'||'o'||'i'||'e'||'a')
之类的多个值来束缚(str[i]==('u'||'o'||'i'||'e'||'a'))
运算符并不用于检查某个值是否是一组值中的一个。
||
运算符是逻辑或运算符。它将两个操作数都视为布尔值,并根据操作数求值为0或1。 C standard的6.5.14节详细介绍了此运算符的使用:
2 每个操作数应具有标量类型。
3 如果
||
运算符的两个操作数中的任何一个不等于0,则其结果为1;否则,结果为0。结果的类型为int
。4 与逐位
|
运算符不同,||
运算符保证从左到右的求值;如果对第二个操作数求值,则在第一个和第二个操作数的求值之间有一个序列点。如果第一个操作数比较不等于0,则不计算第二个操作数。
由于C没有真正的布尔类型,所以任何整数值(包括字符常量)都可以作为||
的操作数。因此,任何非零值都将被视为true,而零将被视为false。另外,请注意上面第4段中的内容,该运算符具有“短路”评估功能,这意味着如果仅通过查看左侧即可知道该运算符的结果,则不会评估右侧。
现在,将其应用于表达式。首先:
if (str[i]=='u'||'o'||'i'||'e'||'a')
由于此处要处理多个运算符,因此需要应用详细的here运算符优先级规则。由于相等比较运算符==
的优先级高于逻辑OR运算符||
,因此,其解析如下:
if ((str[i]=='u')||'o'||'i'||'e'||'a')
因此,我们首先评估str[i]=='u'
。根据{{1}}是否为str[i]
,它可以是0或1。然后我们评估第一个'u'
,所以我们有||
或1||'o'
。
在第一种情况下,左侧操作数为1,因此不评估右侧上方的第4段,其中包括其他0||'o'
运算符,因此最终结果为1,即为true,这是期望的结果。在第二种情况下,0为假,因此我们看一下右边的||
。这是一个字符常量,其值是用于编码字符'o'
的值。如果您的系统使用ASCII(很可能会这样做),则该值为111。由于这是一个非零值,因此整个表达式'o'
的计算结果为1,即true。同样,由于0||'o'
的短路行为,由于左侧为true,因此未评估下一个||
运算符。这意味着上面的表达式总是正确的。
现在转到第二个表达式:
||
首先评估的是if (str[i]==('u'||'o'||'i'||'e'||'a'))
。 'u'||'o'
字符的ASCII码为117,该字符非零,因此第一个'u'
的结果为1,右侧为||
的运算符,不进行评估。现在,您有了||
。除非str[i] == 1
包含不可打印的字符,否则您将永远找不到编码为1的字符,因此该表达式的计算结果始终为0,即false。
C没有内置的运算符来检查值是否是集合的成员,这意味着您需要显式检查str
每个字符:
str[i]
或者您可以创建一个字符数组来检查并遍历它们:
if ((str[i]=='u') || (str[i]=='o') || (str[i]=='i') || (str[i]=='e') || (str[i]=='a'))
或者您可以使用char vowels[5] = "aeiou"; // an array of char, but NOT a string
int found = 0;
for (int j = 0; j < sizeof(vowels); j++) {
if (str[i] == vowels[j]) {
found = 1;
break;
}
}
if (found) {
...
来为您遍历所有值:
strchr
或将if (strchr("aeiou", str[i]))
用于失败情况:
switch
答案 4 :(得分:0)
||
运算符不允许您以这种方式“链接”条件。 a || b || c
的值为(a || b) || c
-a || b
的结果(将为0或1)将与c
或。
对于您要执行的操作,最干净的选择是使用Machine_1在对Tim Biegeleisen的答案的评论中建议的strchr
:
#include <string.h>
...
if ( str[i] >= 0 && strchr( "aeiou", str[i] ) )
{
// str[i] is one of 'a', 'e', 'i', 'o', or 'u'
}
我检查str[i]
是否为负数,因为chux声称将str[i]
的负值传递给strchr
会导致不确定的行为;但是,从标准来看,我认为这不是真的:
7.24字符串处理
7.24.1字符串函数约定
...
3对于本节中的所有功能,每个字符都应被解释为具有以下类型:unsigned char
(因此,每种可能的对象表示形式都是有效的,并且具有 不同的值)。
但是,出于理智的考虑,我们还是将其保留。