读书人

一个关于字符串拼接的有关问题

发布时间: 2013-01-19 11:41:36 作者: rapoo

一个关于字符串拼接的问题
本帖最后由 antiMight 于 2012-12-22 10:27:29 编辑 我用strncpy和strncat来拼接字符串,第一种是直接多次调用,第二种是串接调用,应该效率高点,看起来两个结果应该是一样的才对,但是第二个输出结果有问题,我知道是tbuf的问题,把三个调用tbuf的地方换成三个就是对的,但是为什么呢?这两种方式应该是一样的吧?不一样的只是第二个cat时是直接从上一次的结尾赋值,即使我在_itoa里用了相同的tbuf,strncat后不是会直接拷贝的吗?拷贝完应该就是正确的到buf里了才对吧,谁来解释下?

char tbuf[4] = {0};
char buf[1024] = {0};

strncpy(buf, "\n", 2);
strncat(buf, _itoa(1, tbuf, 10), 3);
strncat(buf, ":", 2);
strncat(buf, _itoa(2, tbuf, 10), 3);
strncat(buf, ":", 2);
strncat(buf, _itoa(3, tbuf, 10), 3);
strncat(buf, "\n", 2);

std::cout << buf<< std::endl;//1:2:3

strncat(strncat(strncat(strncat(strncat(strncat(
strncpy(buf, "\n", 2),
_itoa(1, tbuf, 10), 3),
":", 2),
_itoa(2, tbuf, 10), 3),
":", 2),
_itoa(3, tbuf, 10), 3),
"\n", 2);

std::cout << buf<< std::endl;//1:1:1

[解决办法]
第一,LZ知道_itoa返回什么?
第二,对于这种“套娃”式的函数调用,LZ能否说出它的调用顺序?

为了方便讨论,代码简化如下:

char tbuf[4] = {0};
char buf[1024] = {0};

strncat(buf, _itoa(1, tbuf, 10), 3);
strncat(buf, _itoa(2, tbuf, 10), 3);

buf[0] = 0;
strncat(strncat(buf, _itoa(1, tbuf, 10), 3), _itoa(2, tbuf, 10), 3);

没问题的代码就不讨论了,
单单来看strncat(strncat(buf, _itoa(1, tbuf, 10), 3), _itoa(2, tbuf, 10), 3);这句。

我没有看debugger的执行过程,但从过去看的经验,以及由此建立的对函数调用的理解,要执行这句,先是最外层的strncat压参,而且是从右向左压的,所以是:
先入3,
为了压第二个参数,先执行了_itoa(2, tbuf, 10),返回tbuf压参,同时tbuf的内容是2
为了压第一个参数,要执行strncat(buf, _itoa(1, tbuf, 10), 3),即内部的strncat,

为了执行内部的strncat,同样也是先压3,
再执行_itoa(1, tbuf, 10),这时返回tbuf,但是tbuf的内容已经是1了
压buf

此时内部strncat完成调用,返回buf,压参

然后外部strncat开始调用。

至此,可以清楚错误在哪里了。
LZ可以自行用debugger跟踪此过程,对比顺序调用的过程。

简言之,就是压参,调用,返回这样一个递归的过程(即要算什么,必须先算什么,这样一个依赖)。

最后一句话,不要过早优化。

读书人网 >C语言

热点推荐