我正在学习C。
我发现当我尝试并从语言中获得已有程序员的反馈时,我学习编程很好。
我决定编写自己的strcmp()
函数,因为我认为我可以:)
int strcompare(char *a, char *b) {
while (*a == *b && *a != '\0') {
a++;
b++;
}
return *a - *b;
}
我试图通过在while
的条件下递增指针来使其工作,但无法弄清楚如何执行return
。我正在寻找 C style 代码,尽可能多地在一行上执行:)
我可以从已建立的C程序员那里获得一些反馈吗?这段代码可以改进吗?我有什么坏习惯吗?
感谢。
答案 0 :(得分:3)
如果你想在while语句中做所有事情,你可以写
while (*a != '\0' && *a++ == *b++) {}
我个人并不是这种编程风格的忠实粉丝 - 读者在尝试理解它时需要精神上“解包”操作的顺序(并且如果代码有问题,则需要解决)。内存错误在C中特别隐蔽,在超出原始原因的情况下,将内存覆盖在应该超出或超出之前的一个字节可以导致各种无法解释的崩溃或错误。
现代C编程风格强调正确性,一致性和纪律性,而不是简洁性。简洁的表达式功能,如增量前和增加后的操作,最初是让编译器生成更好的机器代码的一种方式,但优化者现在可以轻松地自己做这些。
正如@sbi所写,我更喜欢const char *
个参数而不是普通的char *
个参数。
答案 1 :(得分:2)
a
和b
的内容。它应该通过指向const
字符串来宣布它。 答案 2 :(得分:1)
我不知道,因为尽可能多的时候被认为是C风格......我更喜欢将(Perfuscated)Perl与...联系起来..
请不要这样做。最好的办法是每行一个命令。当您尝试调试代码时,您将理解为什么:)
对你的实现:对我来说似乎很好,但是我会把条件设置为* b也不是'\ 0',因为你不知道a总是大于b ...否则你冒险阅读未分配的记忆......
答案 3 :(得分:1)
您可能会从eglibc-2.11.1
找到这个有趣的内容。它与您自己的实现并没有太大的不同。
/* Compare S1 and S2, returning less than, equal to or
greater than zero if S1 is lexicographically less than,
equal to or greater than S2. */
int
strcmp (p1, p2)
const char *p1;
const char *p2;
{
register const unsigned char *s1 = (const unsigned char *) p1;
register const unsigned char *s2 = (const unsigned char *) p2;
unsigned reg_char c1, c2;
do
{
c1 = (unsigned char) *s1++;
c2 = (unsigned char) *s2++;
if (c1 == '\0')
return c1 - c2;
}
while (c1 == c2);
return c1 - c2;
}
答案 4 :(得分:0)
一个非常微妙的错误:strcmp
比较解释为unsigned char
的字节,但您的函数将它们解释为char
(在大多数实现中都签名)。这将导致非ascii字符在ascii之前而不是之后排序。
答案 5 :(得分:0)
如果(insigned)char的限制因整数溢出而等于或大于int的限制,则此函数将失败。
例如,如果你在DSP上编译它有16位字符,限制为0 ... 65536和16位int,限制为-32768 ... 32767,那么如果你试图比较字符串像 “/ uA640”和“A”结果将是否定的,这是不正确的。
这是异国情调和奇怪的问题,但在你编写通用实现时会出现。