本文介绍了嗯,好奇的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 以下代码实现了一个类似strcat的函数,它可以接收一个 变量的参数。我认为如果我保持一个指向字符串末尾的 指针会更快,因为它是构建的,所以strcat()会 并不总是必须找到结束当字符串变长并且 更长时间。为了测试这个,我用一个 指针列表调用了vstrcat()函数,然后在循环中使用常规的strcat()函数来构建 相同的字符串。经过10,000,000次迭代后,常规strcat()赢得每次 时间,有时甚至多达10秒。我已经尝试了几种不同的方法(可以看到vstrcat() 函数中注释的代码)但是strcat()总是获胜。这是使用我的旧DOS C 编译器。在我的UNIX机器上,它们甚至都是。 / ******************************** ****************** ******************** / / *档案ID。 vstrcat.c。 * / / *作者:Stan Milam。 * / / *写日期:01 Jun.92。* / / *描述:* / / *实现一个变量字符串串联函数将* / / *比连续调用strcat()更有效。 * / / * * / / *************************** *********************** ******************** / #include< errno.h> #include< stddef.h> #include< string.h> #include< stdarg.h> / ************************* ************************* ******************** / / *名称:* / / * vstrcat() - 快速,字符串连接。 * / / * * / / *说明:* / / *此函数接收可变数量的字符串指针* / / *并将它们连接在一起。唯一的两个要求* / / *是第一个参数,它将是* / / *连接的目标,必须有足够的空间来包含整个* / / *连接字符串。第二个要求是变量* / / *字符串指针必须由NULL指针终止。 * / / * * / / *参数:* / / * char * string - 指向字符串的指针* / / *剩余字符串将被连接。 * / / *其余参数的数量可能不同,但必须是* / / *指向字符串的指针并且以NULL结尾。 * / / * * / / *返回:指向连接字符串的指针。 * / / * * / / *************************** *********************** ******************** / char * vstrcat(char * string,...) { if(string == NULL) errno = EINVAL; else { va_list argptr; char * end,* wrk; / *************************************** *********** ************ / / *获取指针列表的地址。然后找到字符串的* / / *初始端。 * / / *************************************** *********** ************ / va_start(argptr,string); end = * string == 0? string:string +(strlen(string)); / ************************** ************************ ************ / / *拉每个指针从列表中连接到结尾* / / *并保持整个字符串的结尾。这样* / / *我们只计算一次添加的字符数。这极大地加快了* / / *的过程。 * / / *************************************** *********** ************ / while(!((wrk = va_arg(argptr,char *) )== NULL)){ / * strcat(end,wrk); * / strcpy(end,wrk); end + = strlen(wrk); } va_end(argptr); } 返回字符串; } #ifdef测试 #include< time.h> #include" adjust.h" int main(void) { int x_sub; long l_sub; time_t begin,end; char wrkbuf [1000]; char * wrkarray [] = { "这是一个, 串串, 我们将连接, 非常有效地总是, 知道字符串结尾的位置。 ", "这使得vstrcat()多了, 比连续调用strcat更有效!, NULL }; begin = time(NULL); for(l_sub = 0; l_sub< 10000000; l_sub ++){ memset(wrkbuf,0,sizeof(wrkbuf)); vstrcat(wrkbuf,wrkarray [0], wrkarray [ 1], wrkarray [2], wrkarray [3], wrkarray [4], wrkarray [5], wrkarray [6], wrkarray [7], wrkarray [8]); } end = time(NULL); printf("%ld迭代vstrcat()的总时间:%ld \ n", l_sub,(长)结束 - 开始); begin = time(NULL); for( l_sub = 0; l_sub< 10000000; l_sub ++){ memset(wrkbuf,0,sizeof(wrkbuf)); for(x_sub = 0; wrkarray [x_sub] ; x_sub ++) strcat(wrkbuf,wrkarray [x_sub]); } end = tim e(NULL); printf(" strcat()的总时间:%ld \ n",(long)end - begin); 返回0; } #endif / * TEST * / The following code implements a strcat-like function which can receive avariable number of arguments. I thought it would be faster if I kept apointer to the end of the string as it is built so that strcat() wouldnot always have to find the end of the string as it gets longer andlonger. To test this I called the vstrcat() function with a list ofpointers, then use the regular strcat() function in a loop to build thesame string. After 10,000,000 iteration the regular strcat() won everytime, sometimes by as much as 10 seconds. I''ve tried several differentapproaches (as can be seen with code commented out in the vstrcat()function) but strcat() always wins. This is using my old DOS Ccompiler. On my UNIX machine they are about even./************************************************** ********************//* File Id. vstrcat.c. *//* Author: Stan Milam. *//* Date Written: 01 Jun. 92. *//* Description: *//* Implement a variardic string concatenation function which will *//* be much more efficient than successive calls to strcat(). *//* *//************************************************** ********************/ #include <errno.h>#include <stddef.h>#include <string.h>#include <stdarg.h> /************************************************** ********************//* Name: *//* vstrcat() - Fast, string concatenation. *//* *//* Description: *//* This function receives a variable number of string pointers *//* and concatenates them together. The only two requirements *//* is that the first argument which will be the target of the *//* concatenation must have enough space to contain the entire *//* concatenated string. The second requirement is the variable *//* string pointers must be terminated by a NULL pointer. *//* *//* Arguments: *//* char *string - A pointer to a character string where the *//* remaining character string will be concatenated. *//* The remaining arguments may vary in number, but must be *//* pointers to character strings and be NULL terminated. *//* *//* Returns: A pointer to the concatenated string. *//* *//************************************************** ********************/ char *vstrcat(char *string, ...){if ( string == NULL )errno = EINVAL;else {va_list argptr;char *end, *wrk; /************************************************** ************//* Get the address to the list of pointers. Then find the *//* initial end of the string. *//************************************************** ************/ va_start(argptr, string);end = *string == 0 ? string : string + (strlen(string)); /************************************************** ************//* Pull each pointer from the list and concatenate to the end *//* and maintain the end of the string throughout. This way *//* we only count the characters added once. This speeds up *//* the process tremendously. *//************************************************** ************/ while (!((wrk = va_arg(argptr, char *)) == NULL)) {/*strcat( end, wrk );*/strcpy( end, wrk );end += strlen( wrk );} va_end(argptr);}return string;} #ifdef TEST#include <time.h>#include "adjust.h" intmain( void ){int x_sub;long l_sub;time_t begin, end; char wrkbuf[1000];char *wrkarray[] = {"This is a ","bunch of strings ","that we will concatenate ","very efficiently by always ","knowing where the end of the string is going to be. ","This makes vstrcat() much ","more efficient than successive calls to strcat!",NULL}; begin = time(NULL);for ( l_sub = 0; l_sub < 10000000; l_sub++ ) {memset(wrkbuf, 0, sizeof(wrkbuf) );vstrcat(wrkbuf, wrkarray[0],wrkarray[1],wrkarray[2],wrkarray[3],wrkarray[4],wrkarray[5],wrkarray[6],wrkarray[7],wrkarray[8]);}end = time(NULL);printf("Total time for %ld iterations of vstrcat(): %ld\n",l_sub, (long) end - begin); begin = time(NULL); for( l_sub = 0; l_sub < 10000000; l_sub++ ) {memset(wrkbuf, 0, sizeof(wrkbuf) );for ( x_sub = 0; wrkarray[x_sub]; x_sub++ )strcat( wrkbuf, wrkarray[x_sub] );} end = time(NULL);printf("Total time for strcat(): %ld\n", (long) end - begin);return 0;}#endif /* TEST */推荐答案 Stan Milam写道: Stan Milam wrote: errno = EINVAL; EINVAL不是标准C. char * wrkarray [] = {这是一个,串串,我们将连接,非常有效地永远,知道字符串末尾的去向成为。 ","这使得vstrcat()比strcat的连续调用更有效!,更有效!, NULL 那个数组有8个元素。 vstrcat(wrkbuf,wrkarray [0], wrkarray [1], wrkarray [2], wrkarray [3] ], wrkarray [4], wrkarray [5], wrkarray [6], wrkarray [7], wrkarray [8]); errno = EINVAL;EINVAL isn''t standard C. char *wrkarray[] = { "This is a ", "bunch of strings ", "that we will concatenate ", "very efficiently by always ", "knowing where the end of the string is going to be. ", "This makes vstrcat() much ", "more efficient than successive calls to strcat!", NULLThat array has 8 elements. vstrcat(wrkbuf, wrkarray[0], wrkarray[1], wrkarray[2], wrkarray[3], wrkarray[4], wrkarray[5], wrkarray[6], wrkarray[7], wrkarray[8]); wrkarray [8]是8元素数组的第9个元素。 - pete wrkarray[8] is the ninth element of an 8 element array. --pete Stan Milam写道:Stan Milam wrote: .... snip ... char * wrkarray [] = {这是一个,一串字符串,我们将连接,总是非常有效地,知道字符串结尾的位置。 ","这使得vstrcat()比strcat的连续调用更有效,更高效!, NULL }; begin = time(NULL); for(l_sub = 0; l_sub< 10000000; l_sub ++){ memset(wrkbuf,0,sizeof(wrkbuf)); vstrcat (wrkbuf,wrkarray [0], wrkarray [1], wrkarray [2], wrkarray [3], wrkarray [4], wrkarray [ [5], wrkarray [7], wrkarray [8]); } .... snip ... char *wrkarray[] = { "This is a ", "bunch of strings ", "that we will concatenate ", "very efficiently by always ", "knowing where the end of the string is going to be. ", "This makes vstrcat() much ", "more efficient than successive calls to strcat!", NULL }; begin = time(NULL); for ( l_sub = 0; l_sub < 10000000; l_sub++ ) { memset(wrkbuf, 0, sizeof(wrkbuf) ); vstrcat(wrkbuf, wrkarray[0], wrkarray[1], wrkarray[2], wrkarray[3], wrkarray[4], wrkarray[5], wrkarray[6], wrkarray[7], wrkarray[8]); } 没有wrkarray [8],所以你在这里调用未定义的行为 。 - "如果您想通过groups.google.com发布后续内容,请不要使用 损坏的回复链接在文章的底部。点击 " show options"在文章的顶部,然后点击 回复在文章标题的底部。 - Keith Thompson There is no wrkarray[8], so you are invoking undefined behaviorhere. --"If you want to post a followup via groups.google.com, don''t usethe broken "Reply" link at the bottom of the article. Click on"show options" at the top of the article, then click on the"Reply" at the bottom of the article headers." - Keith Thompson CBFalconer写道: CBFalconer wrote: Stan Milam写道: ...剪辑。 .. Stan Milam wrote: ... snip ... char * wrkarray [] = {"这是一个,串串, ;我们将通过始终,非常有效地连接,,知道字符串结尾的位置。 ","这使得vstrcat()比strcat的连续调用更有效,更高效!, NULL }; begin = time(NULL); for(l_sub = 0; l_sub< 10000000; l_sub ++){ memset(wrkbuf,0,sizeof(wrkbuf)); vstrcat (wrkbuf,wrkarray [0], wrkarray [1], wrkarray [2], wrkarray [3], wrkarray [4], wrkarray [ [5], wrkarray [7], wrkarray [8]); } char *wrkarray[] = { "This is a ", "bunch of strings ", "that we will concatenate ", "very efficiently by always ", "knowing where the end of the string is going to be. ", "This makes vstrcat() much ", "more efficient than successive calls to strcat!", NULL }; begin = time(NULL); for ( l_sub = 0; l_sub < 10000000; l_sub++ ) { memset(wrkbuf, 0, sizeof(wrkbuf) ); vstrcat(wrkbuf, wrkarray[0], wrkarray[1], wrkarray[2], wrkarray[3], wrkarray[4], wrkarray[5], wrkarray[6], wrkarray[7], wrkarray[8]); } 有没有wrkarray [8],所以你在这里调用未定义的行为。 There is no wrkarray[8], so you are invoking undefined behavior here. 我修复了它。它仍然较慢。 I fixed it. It is still slower. 这篇关于嗯,好奇的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 09-17 14:39