修改现有的 char* 或创建临时 char*?
modify existing char* or create a tmp char*?
某些语言,例如 Java,需要您创建另一个字符串才能解决某些类型的问题。但是当涉及到 C 时,什么时候应该创建另一个字符串,什么时候应该简单地修改现有的字符串?
以下面的代码为例:
char *removeTags(char *s, int length)
{
if (!s || length < 1)
{
exit(EXIT_FAILURE);
}
char *tmp = calloc(length, sizeof(char));
int count = 0;
for (int i = 0; i < length; i++)
{
if (s[i] == '<')
{
for (int k = i; k < length; k++)
{
if (s[k] == '>')
{
i = k;
break;
}
}
}
else if (s[i] != '>' && s[i] != '<')
{
tmp[count] = s[i];
count++;
}
}
return tmp;
}
应该这样调用:
char *foo = (char *)calloc(length, sizeof(char)); foo = removeTags(foo, strlen(foo));
如果我只是修改 char *s
而不是创建 char *tmp
来帮助我会更好吗?
如果函数处理字符串,那么第二个参数是多余的,error-prone
char *removeTags(char *s, int length)
如果你想创建一个新的字符串,那么这个函数必须声明为
char * removeTags( const char *s );
即函数参数应具有限定符const
.
如果您想就地更改字符串,则函数必须声明为
char * removeTags( char *s );
请注意,您不能更改字符串文字。
如果您还向函数传递字符串文字,则函数必须声明为
char * removeTags( const char *s );
您可以定义这两个函数,但在这种情况下您需要使用不同的函数名称。
每当您在 C 函数中修改字符串时,都有一个很好的理由来制作字符串的副本并修改 return 副本,同时使您的输入字符串参数成为 const char *
。
您的调用者不会通过传入字符串文字来调用未定义的行为。这可能会使您的整个过程崩溃,例如 SIGSEGV
.
像这样:
char *removeTags(const char *s);
一般情况下,您不需要为字符串操作传递长度,除非您需要限制您正在操作的字符串的范围。
另一个不太重要的原因:调用者可能还没有完成对字符串的处理,可能需要不修改它。
如果您随后通过分析发现额外的复制步骤会导致性能或内存问题,那么您可以创建另一个函数,并像这样调用它:
void removeTagsInPlace(char *s);
请注意 return 值的差异,这使得字符串被修改的事实 in-place 不可能被遗漏。
某些语言,例如 Java,需要您创建另一个字符串才能解决某些类型的问题。但是当涉及到 C 时,什么时候应该创建另一个字符串,什么时候应该简单地修改现有的字符串?
以下面的代码为例:
char *removeTags(char *s, int length)
{
if (!s || length < 1)
{
exit(EXIT_FAILURE);
}
char *tmp = calloc(length, sizeof(char));
int count = 0;
for (int i = 0; i < length; i++)
{
if (s[i] == '<')
{
for (int k = i; k < length; k++)
{
if (s[k] == '>')
{
i = k;
break;
}
}
}
else if (s[i] != '>' && s[i] != '<')
{
tmp[count] = s[i];
count++;
}
}
return tmp;
}
应该这样调用:
char *foo = (char *)calloc(length, sizeof(char)); foo = removeTags(foo, strlen(foo));
如果我只是修改 char *s
而不是创建 char *tmp
来帮助我会更好吗?
如果函数处理字符串,那么第二个参数是多余的,error-prone
char *removeTags(char *s, int length)
如果你想创建一个新的字符串,那么这个函数必须声明为
char * removeTags( const char *s );
即函数参数应具有限定符const
.
如果您想就地更改字符串,则函数必须声明为
char * removeTags( char *s );
请注意,您不能更改字符串文字。
如果您还向函数传递字符串文字,则函数必须声明为
char * removeTags( const char *s );
您可以定义这两个函数,但在这种情况下您需要使用不同的函数名称。
每当您在 C 函数中修改字符串时,都有一个很好的理由来制作字符串的副本并修改 return 副本,同时使您的输入字符串参数成为 const char *
。
您的调用者不会通过传入字符串文字来调用未定义的行为。这可能会使您的整个过程崩溃,例如 SIGSEGV
.
像这样:
char *removeTags(const char *s);
一般情况下,您不需要为字符串操作传递长度,除非您需要限制您正在操作的字符串的范围。
另一个不太重要的原因:调用者可能还没有完成对字符串的处理,可能需要不修改它。
如果您随后通过分析发现额外的复制步骤会导致性能或内存问题,那么您可以创建另一个函数,并像这样调用它:
void removeTagsInPlace(char *s);
请注意 return 值的差异,这使得字符串被修改的事实 in-place 不可能被遗漏。