如何有效(及时)计算C中字符串的长度?
现在我正在做:
int calculate_length(char *string) {
int length = 0;
while (string[length] != '\0') {
length++;
}
return length;
}
但是与strlen()相比它很慢,例如,有没有其他方法可以做到这一点?
感谢。
编辑:我在一个独立的环境中工作,我不允许使用任何外部lib,包括“string.h”。
答案 0 :(得分:41)
size_t
strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s);
return(s - str);
}
与您的代码相比,这可能很好地映射到汇编程序指令,这可以解释一个很大的性能差异。
答案 1 :(得分:9)
查看标准libc中strlen的源代码。标准库中的函数通常是高度优化的。检查出here(在汇编中编码) - 这是来自GNU libc。
size_t
DEFUN(strlen, (str), CONST char *str)
{
int cnt;
asm("cld\n" /* Search forward. */
/* Some old versions of gas need `repne' instead of `repnz'. */
"repnz\n" /* Look for a zero byte. */
"scasb" /* %0, %1, %3 */ :
"=c" (cnt) : "D" (str), "0" (-1), "a" (0));
return -2 - cnt;
}
答案 2 :(得分:9)
strlen()
。可能的情况是,如果有人找到了更好,更快的通用方法,那么strlen就会被替换掉。
答案 3 :(得分:6)
看看GNU C library's strlen()
source。
它使用了许多非显而易见的技巧来提高速度而不会下降到装配,包括:
等
答案 4 :(得分:3)
最简单的方法是致电strlen()
。认真。它已经由您的编译器和/或库供应商优化,以尽可能快地为您的架构。
一个常见的优化是不需要增加计数器,并从指针计算长度:
size_t my_strlen(const char *s)
{
const char *anchor = s;
while(*s)
s++;
return s - anchor;
}
答案 5 :(得分:3)
C字符串为intrinsically inefficient,使用ASCIZ约定有两个原因:
在这种情况下,第一个是学术性的,因为您没有使用标准库,第二个可以通过创建函数或宏来轻松克服,这些函数或宏提供从C字符串到更有效的约定(如Pascal字符串)的转换。关键是如果你不使用C库,你不必成为C约定的奴隶。
答案 6 :(得分:2)
另一种加速计数的方法是使用矢量化!
以下是关于UTF8编码字符串的示例:
更快的UTF-8字符计数,
http://www.daemonology.net/blog/2008-06-05-faster-utf8-strlen.html
答案 7 :(得分:0)
在i386处理器上,libc经常使用strlen
的超优化版本,通常用汇编语言编写。论文“String Length”解释了它们的工作原理。
以下是OpenBSD的一个优化版本。 (他们也有一个portable version。)这是version for the GNU libc。
答案 8 :(得分:0)
上面的一些答案非常好,这是我的看法。 有一个关键字称为“注册”
#include <stdio.h>
size_t strlenNew(char *s);
int main(int argc, char* argv[])
{
printf("Size of \"Hello World\" is ::\t%d",strlenNew("Hello World"));
return 0;
}
size_t strlenNew(char *s)
{
register int i=0;
while(s[i]!='\0') i++;
return i;
}
请在此处阅读:http://gustedt.wordpress.com/2010/08/17/a-common-misconsception-the-register-keyword/和http://msdn.microsoft.com/en-us/library/482s4fy9(v=vs.80).aspx
从第一个链接:
这对数组变量特别有用。数组变量 容易与指针变量混淆。除非紧随其后 a [expr]或sizeof,它的计算结果为第一个地址 元件。如果声明数组寄存器,则所有这些用途都是 禁止;我们只访问个别元素或询问总数 尺寸。这样的寄存器阵列可以更容易地使用,就像它一样 只是优化器的一组变量。没有别名(访问 可能会出现相同的变量通过不同的指针。
因此,有时可能存在性能波动。就个人而言,这是我最喜欢的实现之一,但Sudhanshu和Andomar也提供了一个很好的实现:)
答案 9 :(得分:0)
我有同样的问题,我解决了。关键是for循环的第二个条件:
int longitud(char cad[]){
int i, cont;
cont = 0;
for(i = 0; i < 30 && cad[i] != '\0'; i++){
if(cad[i] != '\0'){
if(cad[i] != ' '){
cont++;
}
}
}
cont--;
return cont;
}
答案 10 :(得分:0)
我没有找到更好的:
内联 size_t mystrlen(char * _)
{ return ((_ == NULL) ? (_[0] != '\0')) ? 0 : (1 + mystrlen(_ + 1)); }
答案 11 :(得分:0)
用于计算字符串长度的基本C程序。
#include <stdio.h>
/**
* Method to calculate string length.
* Returns -1 in case of null pointer, else return string length.
**/
int length(char *str) {
int i = -1;
// Check for NULL pointer, then return i = -1;
if(str == NULL) return i;
// Iterate till the empty character.
while (str[++i] != '\0');
return i; // Return string length.
}
int main (int argc, char **argv) {
int len = 0;
char abc[] = "hello";
len = length(abc);
printf("%d", len);
return 0;
}
注意:为了更好的方法,我们应该始终将数组大小传递给函数以避免内存泄漏。例如,方法的**原型应该是*:*
/**
* @desc calculate the length of str.
* @param1 *str pointer to base address of char array.
* @param2 size = capacity of str to hold characters.
* @return int -1 in case of NULL, else return string length.
**/
int length (char *str, int size);
答案 12 :(得分:-1)
我不太确定你想做什么。
您想重新编写strlen
以使您的代码与标准c-Library兼容,或者您想要管理字符串。
在第一种情况下,我认为你最好直接使用标准库。
另一个案例很有意思:你应该看看c ++字符串类,它具有traits策略的实现(允许快速操作非常大的字符串)。
答案 13 :(得分:-5)
int max;
max = sizeof(str);
return (--max);