c - 输出根据程序中函数调用的位置而变化
问题描述
我目前正在学习 C。为了变得更好,我想做的一件事是模仿标题中的“strcat”函数。为了制作更精确的副本,我将自己函数的输出与原始函数的输出进行了比较。它们使用相同但不同的字符数组。但是,如果在原始函数之后调用它,我自己的函数的输出会发生变化。以下是两种代码变体:
在第一个中,原始的输出是"1234567890123456",正如预期的那样,我自己的输出是"123456789123456"。经过几十次不同的检查后,我发现:一旦将'0'字符作为参数传递给函数,它就会从src[0]中消失:
int main()
{
char dest[10] = "123456789";
char src[70] = "0123456";
printf ("Concatenate |%s| and |%s|\n", dest, src);
char dest1[10] = "123456789";
char src1[70] = "0123456";
printf ("Normal people do: %s\n", strcat(dest1, src1));
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
return 0;
}
但是,如果我像这样简单地重新定位我的函数的 printf:
int main()
{
char dest[10] = "123456789";
char src[70] = "0123456";
printf ("Concatenate |%s| and |%s|\n", dest, src);
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
char dest1[10] = "123456789";
char src1[70] = "0123456";
printf ("Normal people do: %s\n", strcat(dest1, src1));
return 0;
}
这两个函数都将返回“1234567890123456”作为输出。
问题是:这怎么可能?我很好奇,因为这些函数针对两组不同的数组,因此不应该相互影响。由于某种原因,我的函数的行为取决于它在int main()的主体中被调用的时间。
请注意,我特意将 dest[] 数组设置为 10 个字符大,因为我也想在意外情况下模仿原始“strcat”的行为。虽然这可能是问题的核心,如果我改变它,代码在上述两种情况下都可以正常工作。正如我所说,我对问题的性质感兴趣,而不是解决问题的方法。
我不确定我的函数文本是否与此问题相关,但在这里,以防万一:
char *ft_strcat(char *dest, char *src)
{
int dest_end;
int src_count;
dest_end = 0;
src_count = 0;
while (dest[dest_end])
dest_end++;
while (src[src_count])
{
dest[dest_end] = src[src_count];
src_count++;
dest_end++;
}
dest[dest_end + 1] = '\0';
return dest;
}
谢谢你的任何答案。
解决方案
char dest[10] = "123456789";
char src[70] = "0123456";
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
char dest1[10] = "123456789";
char src1[70] = "0123456";
printf ("Normal people do: %s\n", strcat(dest1, src1));
在这两种情况下,使用您自己的函数ft_strcat(dest, src))
或strcat()
其中任何一种,您都会调用未定义的行为,因为char
目标指向的数组无法保存初始化的字符串以及源指向的附加字符串。当超出数组范围写入时,程序的行为是未定义的。
解决方案:
数组dest
和dest1
需要至少18
总共有元素,10
用于保存 "0123456789"
,用于终止空字符7
的附加"0123456"
+元素:1
\0
char dest[18] = "123456789";
char dest1[18] = "123456789";
char src[70] = "0123456";
char src1[70] = "0123456";
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
printf ("Normal people do: %s\n", strcat(dest1, src1));
旁注:
- 该数组
scr1
是多余的,因为它仅用于提供附加字符串,并且它的内容与 .in 中的字符串完全相等src
。您也可以src
用于第二个附加过程:
printf ("Normal people do: %s\n", strcat(dest1, src));
src
并src1
持有每个70
元素,这是不必要的。他们都只需要有8
元素,而不是70
:
src[8] = "0123456";
src1[8] = "0123456";
一种更方便的方法是省略元素的数量,让编译器自动检测所需的元素数量,这也确保您不会忘记计数时的空字符:
src[] = "0123456";
src1[] = "0123456";
- 由于指针
src
及其指向的对象都应在ft_strcat()
declaresrc
as中进行修改char const * const src
。
dest
也可以制作const
,但不要让它成为指向const
char:的指针char * const dest
。
ft_strcat()
关于指针,您还可以调整 的返回类型dest
。
结果是:
char * const ft_strcat(char * const dest, char const * const src)
推荐阅读
- typescript - TS2339:交替类型无法识别属性
- cassandra - 在 Windows 上启动 Cassandra 时出现致命的 Java 错误
- windows - 自删除 PowerShell 脚本会删除所有内容,但不会删除包含/父文件夹
- javascript - 包含隐藏元素的搜索
- python - 如何处理 jupyter-notebook 上的鼠标事件
- docker - 是否可以从 Dockerfile 创建 Singularity 映像?
- python - 将灰度图像转换为二进制时如何使用局部阈值?
- python - Python restframework 返回 ImportError: No module named but no syntax error
- r - 线性回归中的 R 稳健标准误差作为在 glht() 中使用的 lm 对象
- testing - 域错误测试和控制流/数据流测试有什么区别?