-3

我正在尝试编写自己的 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) 警告:函数 'append' 的隐式声明在 C99 中无效

2)警告:格式字符串不是字符串文字(可能不安全)

3) 错误:“追加”的类型冲突

我看不到我在 main 中传递给 append 函数的参数如何与它下面的函数定义发生冲突。

4) 警告:用“char **”类型的表达式初始化“char *”的指针类型不兼容;消除 &

我为什么要在&这里删除?我想我可以一次声明并初始化char指向正确内存地址的指针。

任何帮助深表感谢。

4

4 回答 4

3

1) 警告:函数 'append' 的隐式声明在 C99 中无效

3) 错误:“追加”的类型冲突

append()因为,您在使用它之前没有提供原型。您需要在使用之前添加函数的前向声明。添加

void append(char *start, char *add);

beforemain()或者把函数定义放在前面main()

接下来,万一

 char *start = "start";
 char *add = "add";

start并且add是指向字符串文字的指针。它们通常放置在只读存储器中,这意味着您无法更改内容。任何这样做的尝试都会导致未定义的行为

那么,关于

2)警告:格式字符串不是字符串文字(可能不安全)

printf(start);

在这种情况下是错误的用法。你需要像这样使用它

printf("%s\n", start);

查看手册页printf()获取更多详细信息。

最后,

4) 警告:用“char **”类型的表达式初始化“char *”的指针类型不兼容;消除 &

是因为

char *temp = &start;

你需要使用类似的东西

char *temp = start;   //start is a char *, no need for & here

注意:推荐的签名main()int main(void).

于 2015-04-24T20:51:08.863 回答
2

该短代码存在多个问题。首先你有

警告:函数“附加”的隐式声明在 C99 中无效

这个警告的意思是你需要在使用函数之前声明它们。如果你在使用函数之前没有声明它,编译器将不得不猜测它的参数和返回类型,而且它经常猜测得很糟糕。

继续下一个警告:

警告:格式字符串不是字符串文字(可能不安全)

这是因为您为 提供了一个字符串变量printf,就像警告告诉您的那样,这是不安全的。例如,考虑一下您从用户那里读取输入并将该输入用作格式字符串的情况printf。什么会阻止用户在输入字符串中添加格式代码?而且由于您不传递参数,这些格式的参数从何而来?

现在错误:

错误:“附加”的类型冲突

这是因为第一个问题,编译器错误地猜测了函数的参数或返回类型。


现在讨论另一个不显示为编译器错误或警告的主要问题,即undefined behavior

问题是您的startadd变量指向字符串文字。字符串文字是只读的(实际上,字符串文字是指向不可修改字符数组的指针)。第一个问题是您尝试修改这些数组的内容,第二个问题是这些数组只有需要的大小,并且您在该内存之外进行写入。这两个问题都是未定义行为的原因。

于 2015-04-24T20:55:18.273 回答
2

但这是简单的部分,编译器可以检测到。

更糟糕的是,当您声明startchar *start = "start"时,它仅指向 6 个字符(5 个字母 + 终止 null)的数组。

因此,当您尝试add在其末尾添加时,您会得到未定义的行为(用于写入数组之外)!在这种情况下,您正在编写内存,其他任何可能是=>您的程序可能会中断或段错误。

于 2015-04-24T20:55:25.740 回答
1

C99 在它希望你如何声明事物方面非常严格。

正如 Sourav 所说,1 和 3 是由您的append()函数在文件中声明之前使用的,这会导致编译器为您生成隐式声明。移动append()上面的函数main()来解决这个问题(或添加一个函数原型)。

4 是由这一行引起的:char *temp = &start;

temp这实际上是 a char**,因为您正在获取 a 的地址char*

于 2015-04-24T20:55:46.373 回答