C字符串在C和C ++中为大写
当我在C ++中组合一个大写的函数时,我注意到我没有在C中收到预期的输出。
C ++函数
#include #include #include void strupp(char* beg) { while (*beg++ = std::toupper(*beg)); } int main(int charc, char* argv[]) { char a[] = "foobar"; strupp(a); printf("%s\n", a); return 0; }
按预期输出:
FOOBAR
Cfunction
#include #include #include void strupp(char* beg) { while (*beg++ = toupper(*beg)); } int main(int charc, char* argv[]) { char a[] = "foobar"; strupp(a); printf("%s\n", a); return 0; }
输出是第一个字符缺失的预期结果
OOBAR
有谁知道为什么在C中编译时结果会被截断?
问题是没有序列点
while (*beg++ = toupper(*beg));
所以我们有未定义的行为。 编译器在这种情况下正在做的是在toupper(*beg)
之前评估beg++
toupper(*beg)
在C中,在C ++中它以另一种方式执行它。
while (*beg++ = std::toupper(*beg));
导致未定义的行为。
是否未指定*beg++
在std::toupper(*beg)
之前或之后排序。
简单的解决方法是使用:
while (*beg = std::toupper(*beg)) ++beg;
这条线
while (*beg++ = toupper(*beg));
包含对正在使用两次的实体的副作用。 你无法知道,是否在* beg之前或之后执行了beg ++(在toupper内)。 你很幸运,两个实现都显示了这两种行为,因为我很确定它对C ++来说是一样的。 (但是,对于c ++ 11有一些规则更改,我不确定 – 仍然是,它的风格很糟糕。)
只是将beg ++移出条件:
while (*beg = toupper(*beg)) beg++;
关于上面的答案,’f’永远不会传递到函数内部,你应该尝试使用它:
while ((*beg = (char) toupper(*beg))) beg++;