【问题标题】:condition is false but even then its printing size of s条件为假,但即便如此,它的打印尺寸为 s
【发布时间】:2021-10-29 02:06:33
【问题描述】:
#include<stdio.h>
#include<string.h>

void printlen(char *s,char *t){
    int c=0;
    int len=((strlen(s)-strlen(t)>c)?strlen(s):strlen(t));
    printf("%d",len);
}

void main(){

char *x="abc";
char *y="defgh";
   printlen(x,y);

}

strlen(s) 是 3,strlen(t) 是 5,那么为什么 strlen(s)-strlen(t)&gt;c 评估为 true?

【问题讨论】:

  • 将括号读作if。将问号读作then。将冒号读作else。所以((strlen(s)-strlen(t)&gt;c)?strlen(s):strlen(t)) 计算结果为“if (strlen(s)-strlen(t)>0) then strlen(s) else strlen(t)”
  • 您最好将条件重新组织为(strlen(s) &gt; strlen(t)),或者如果c 可能不为零,那么(strlen(s) &gt; strlen(t) + c)。避免减去无符号数。

标签: c pointers strlen


【解决方案1】:

strlen 函数返回一个 size_t 类型的值,它是无符号的。

所以从 unsigned 5 中减去 unsigned 3 会得到一个非常大的无符号数。此数字大于 0,因此条件为真,导致 strlen(s) 被评估并分配给 len

减法的结果应转换为int 以正确存储带符号的值。

int len=(((int)(strlen(s)-strlen(t))>c)?strlen(s):strlen(t));

更好的是,转换每个strlen 的结果以避免从无符号到有符号的超出范围的转换,这是实现定义的:

int len= ((int)strlen(s)-(int)strlen(t))>c)?strlen(s):strlen(t);

【讨论】:

  • ssize_t,取决于预期的长度范围(实际上,int 可能没问题)。
  • @rakeshpatel 很高兴我能帮上忙。如果您觉得有用,请随时 accept this answer
  • int 范围外的值转换为int 是实现定义的。 (int) strlen(s) - (int) strlen(t) 将优于 (int) (strlen(s) - strlen(t)),因为前者仅在一个字符串长度超过 int 范围的极少数情况下具有实现定义的行为,而后者在 @987654337 的常见情况下具有实现定义的行为@ 比 t 短(以及当字符串长度之间的差异超过 int 范围时)。
  • strlen(s) &gt; strlen(t) + c 可能更好,只有当strlen(t) + c 超出size_t 的范围时才会出现问题。
【解决方案2】:
int len=((strlen(s)-(int)strlen(t)>c)?strlen(s):strlen(t));
printf("%d",len);

相等:

int len;

if((strlen(s) - strlen(t) > c)
    len = strlen(s);
else
    len = strlen(t);
printf("%d",len);

首先,printf("%d",len); 是无条件的。无论len(s) - strlen(t) &gt; ctrue 还是falseprintf("%d",len); 都会被执行。

其次,strlen返回size_t,这是unsigned long long的别名,所以(strlen(s) - strlen(t) &gt; c)总是true

您应该将其类型转换为int

int len=(((int)strlen(s)-(int)strlen(t)&gt;c)?strlen(s):strlen(t));

【讨论】:

  • size_t 通常不是unsigned int。它通常有更大的类型,通常是unsigned long long
  • (int)strlen(s)-strlen(t) 没用。因为size_t 是无符号的,并且几乎总是与int 一样宽,所以- 运算符会将(int)strlen(s) 转换为size_t,结果将是无符号的。
猜你喜欢
  • 1970-01-01
  • 2010-11-09
  • 2017-01-24
  • 2018-08-23
  • 2014-10-31
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多