考虑以下两个功能。这两个函数计算字符在具有指定长度的字符串中出现的次数。
pandas
显然,这两个函数做同样的事情。除了第一个函数比第二个函数更易读之外,第二个函数是否更有效,因为它避免了局部变量?我确信这些特定的功能实在太简单,无法衡量真正的差异。我更多地采用一般性或理论性的方式。
用户是否应该避免将输入参数用作临时存储(除了可读性)?我没有询问指针,输入可以通过函数改变。编译器是否以不同的方式解释这两个函数,这可能导致函数1成为首选函数?
我搜索了这些问题,我确实找到了一些相关的问题,但没有一个我能找到的讨论效率。
答案 0 :(得分:2)
编写您最容易阅读/编写/维护的代码。使用优化进行编译时,函数之间的差异可能会消失。
您可能想要考虑一些可以编写更灵活功能的事情,或者至少:更容易阅读的代码。这个答案将更多地关注编码风格,而不是问题 哪个最好,X或Y ,因为答案几乎总是 这取决于ž 强>
鉴于您允许调用为字符串长度传递0
值,您可以编写如下内容:
int get_char_count(const char *str, char c)
{
int count = 0;
while(*str++) {
if (*str == c) {
++count;
}
}
return count;
}
对我而言,这看起来像代码量最少,易于阅读,易于维护。 缺点是:
'\0'
个字符的字符串(即char[][]
)'\0'
字符的字符串如果要支持这些用例,则必须添加长度参数。但即便如此,我只是将它添加到函数中,而不是调用strlen
:
int get_char_count(const char *str, char c, unsigned int len)
{
int count = 0;
if (!len) {
while(*str++) {
if (*str == c) {
++count;
}
}
return count; // return early
}
//len is given
while (len--) {
if (str[len] == c) {
++count;
}
}
return count;
}
现在我可以指定要迭代的字符数,而不是返回'\0'
,我可以使用此函数,例如,计算给定字符的出现次数。字符串数组:
第一种情况(char [][]
)的工作原理是因为数组如何存储在内存中:数组是一个连续的内存块,所有值都是连续存储的。如果您知道所述块的总大小,则可以使用char[][]
,就像它是一个大字符串一样。结果是:只需要1个函数调用来计算数组所有元素中的字符。
最后一种情况几乎是一回事,因为示例中的字符串实际上是如何存储字符串数组。
第二个例子(以部分字符串计算)是不言而喻的:您可以指定要检查的字符数,而不是指定完整字符串的长度。
对于缺少终止空字符的字符串,可以使用相同的方法
因为这是一个相当简单的实现功能,所以通常会看到大多数括号被省略:
while (*str++)
if (*str == c)
++count;
//or even
while(len--) count += str[len] == c;
最后一个版本在技术上是有效的,但它并不容易阅读。忽略单行if和简单循环的括号是相当常见的,但是几年前就像the goto fail
bug一样导致了错误。
最后一个与风格相关的事情:
当使用指针迭代字符串时,就像我在第一个片段中所做的那样,有些人会告诉你最好的办法是创建一个增量的本地指针:
int get_char_count(const char *str, char c)
{
int count = 0;
const char *local = str;
while(*local++) {
if (*local == c) {
++count;
}
}
return count;
}
这里的明显优势是你没有丢失传入的原始位置/指针。如果你以后在函数中添加了一些内容,你可以随时重新分配,或者根据str
分配新的指针。