我正在尝试编写自己的strcat版本(我称之为"追加")。这就是我所拥有的:
#include <stdio.h>
int main() {
char *start = "start";
char *add = "add";
append(start, add);
printf(start);
}
void append(char *start, char *add) {
//get to end of start word
char *temp = &start;
while (*temp != '\0') {
temp++;
}
*temp = *add;
while (*temp != '\0') {
*temp = *add;
}
}
当我编译时,我得到3个警告和错误:
1)警告:隐含的功能声明&#39;追加&#39;在C99中无效
2)警告:格式字符串不是字符串文字(可能不安全)
3)错误:&#39;追加&#39;
的冲突类型
我不知道我传递给append函数的参数如何与它下面的函数定义发生主要冲突。
4)警告:不兼容的指针类型初始化&#39; char *&#39;表达式为&#39; char **&#39 ;;删除&amp;
为什么我要在此处删除&
?我以为我可以一次声明并初始化我的char
指向正确的内存地址。
非常感谢任何帮助。
答案 0 :(得分:3)
1)警告:C99中函数'append'的隐式声明无效
和
3)错误:'追加'的冲突类型
因为在使用之前没有提供rInput
的原型。您需要在使用之前添加函数的前向声明。添加
append()
在void append(char *start, char *add);
之前或将函数定义放在main()
之前
接下来,在
的情况下main()
char *start = "start";
char *add = "add";
和start
是指向字符串文字的指针。它们通常放在只读存储器中,意味着您无法更改内容。任何这样做的尝试都会导致undefined behavior。
然后,关于
2)警告:格式字符串不是字符串文字(可能不安全)
add
在这种情况下,是错误的用法。您需要像
一样使用它printf(start);
查看printf("%s\n", start);
的{{3}}了解详情。
最后,
4)警告:不兼容的指针类型使用'char **'类型的表达式初始化'char *';删除&amp;
是因为
printf()
你需要使用像
这样的东西char *temp = &start;
注意:char *temp = start; //start is a char *, no need for & here
的推荐签名为main()
。
答案 1 :(得分:2)
您的短代码存在多个问题。首先你有
警告:隐含的功能声明&#39;追加&#39;在C99中无效
此警告的含义是您在使用之前需要声明函数。如果你在使用它之前没有声明一个函数,编译器将不得不猜测它的参数和返回类型,并且经常猜测它很糟糕。
继续下一个警告:
警告:格式字符串不是字符串文字(可能不安全)
这是因为你向printf
提供了一个字符串变量,这就像警告告诉你的那样,是不安全的。例如,考虑一下您从用户那里读取输入的情况,并将该输入用作printf
的格式字符串。什么会阻止用户在输入字符串中添加格式代码?既然你没有传递参数,那么这些格式的参数会来自何处?
现在错误:
错误:&#39;追加&#39;
的冲突类型
这是因为第一个问题,编译器错误地猜到了函数的参数或返回类型。
现在还有另一个 主要 问题,它不会显示为编译器错误或警告,即undefined behavior。
问题是您的start
和add
变量指向字符串文字。字符串文字是只读(实际上,字符串文字是指向不可修改字符数组的指针)。第一个问题是你试图修改这些数组的内容,第二个问题是数组只有你需要的那么大,你在那个内存之外写。这两个问题都是未定义行为的原因。
答案 2 :(得分:2)
但这是容易的部分,编译器可以检测到的内容。
更糟糕的是,当你将start
声明为char *start = "start"
时,它只指向一个包含6个字符的数组(5个字母+终止空值)。
因此,当您尝试在其末尾添加add
时,您将获得未定义的行为(用于在数组之外写入)!在这种情况下,你正在编写内存,其他任何可能是=&gt;你的程序可能会破坏或发生段错误。
答案 3 :(得分:1)
C99在如何宣布事情上的限制非常严格。
Sourav说,
1&amp; 3是由您在文件中声明之前使用的append()
函数引起的,这会导致编译器为您生成隐式声明。将append()
函数移到main()
上方以修复它(或添加函数原型)。
4是由此行引起的:char *temp = &start;
temp
这里实际上是char**
,因为您正在获取char*