高效的 strcpy 并将指针移动到目标的末尾
Posted
技术标签:
【中文标题】高效的 strcpy 并将指针移动到目标的末尾【英文标题】:Efficient strcpy and move pointer to end of destination 【发布时间】:2021-12-28 21:37:39 【问题描述】:我需要将一些类似 c 的字符串复制到另一个并移动它的指针。我围绕 strcpy 编写了用于移动目标指针的包装器,我想知道是否有更好的方法来做到这一点。
这就是我现在所做的:
#include <string.h>
#include <stdio.h>
// copy t to *s and move **s pointer to the end
void write_obj(char ** s, char * t)
strcpy(*s, t);
(*s) += strlen(t);
void main()
char json_str[1024];
char* json_str_ptr;
char** s = &json_str_ptr;
printf("Init:\r%08x\n", *s);
write_obj(s, "12345678");
printf("%08x\n", *s);
write_obj(s, "1234");
printf("%08x\n", *s);
有没有更好和/或更有效的方法来做到这一点?
如何只复制一个字符一个字符并在循环中递增(*s)
,直到我到达源数组或目标数组末尾的\0
?
我现在正在 msvc 编译器上对此进行测试,但代码将针对 STM32 微控制器,这将是非常热门的功能。
【问题讨论】:
【参考方案1】:如果有更好的方法来做到这一点。
如果有类似 linux 的例程可用,请使用 *s = stpcpy(*s, t)
如果编译器有很好的优化,可以使用*s += sprintf(*s, "%s", t);
。 (如果长度超过INT_MAX
,则失败。)
各种其他O(n)
方法。 restrict
基本上是指s, *s, t
的数据指针不重叠。
void write_obj(char * restrict * restrict s,
const char * restrict t)
size_t len = strlen(t);
memcpy(*s, t, len + 1);
*s += len;
使用上述方法(所有 O(n)),返回字符串的 end 指针避免了重复 strcat()
的 Schlemiel the Painter's algorithm 问题 O(n*n)
。
【讨论】:
1.标记为stm32
- 所以没有 linux 2. GCC(主要用于 stm32 开发)不太好。 godbolt.org/z/dP6hzKK1E 3. strlen + memcpy 在这个目标上的效率低于简单的复制功能。没有适用于 stm32 目标
@0___________ 1. 即使 Linux 没有完全移植到 stm32,stm32 stpcpy()
也可能存在,或者很容易制作一个像样的。 2. 有趣的示例代码。 return dest - 1;
看起来不对劲。我希望return dest;
从sprintf()
返回不包括'\0'
。 3. 带有strcpy()
的简单副本仍然要求strlen()
调用形成len
。回复:效率,无论哪种方式都是一样的O(n)
。 4. “None works for stm32 target”不清楚。您是否建议 write_obj()
不适用于 stm32?
@0___________ 也许我们应该 use char *copyandmove(char * restrict dest, const char * restrict src) return dest + sprintf(dest, "%s", src);
让编译器利用非重叠数据。
您的示例没有显示任何内容。它简单地在主函数中打印一个字符串。 restrict
在这种情况下不会改变任何东西(功能代码)。 sprintf
或 strlen + memcpy
对于这个目标来说效率不是很高。 godbolt.org/z/qPjocb63b Linux 从未移植到 stm32 uC,因为它们没有足够的资源来运行它(STM32MP 不是 uC - 它们是具有 M4 uC 协处理器的应用处理器)。可能可以将 Linux 移植到 stm32H7 或 stm32l4s9 处理器,因为它们有 1M 和 640kB od SRAM。 (H7 SRAM区域不连续,移植难度较大)
它们还需要额外的非易失性存储,因为它们没有足够的闪存来容纳 Linux 内核。【参考方案2】:
-
解析 jsons 通常不需要微优化。
IMO 自己的功能会比 strlen + memcpy 更好(在 stm32F429 上测试)。 memcpy 优化通常最适合较长的复制操作 - json 字符串通常很短。
最好尽可能避免副作用。使用函数返回值而不是双指针。
char *copyandmove(char *dest, const char *src)
while((*dest++ = *src++));
return dest - 1;
int main(void)
char x[100];
char *s = x;
s = copyandmove(s, "Hello");
s = copyandmove(s, "");
s = copyandmove(s, " World");
printf("Result: `%s`\n", x);
【讨论】:
以上是关于高效的 strcpy 并将指针移动到目标的末尾的主要内容,如果未能解决你的问题,请参考以下文章