在编译和执行以下程序时,我在编译期间收到警告,并在执行期间发生seg错误。
警告
program.c: In function main:
program.c:17: warning: passing argument 2 of convertString from incompatible pointer type
第17行是对convertString(input, &output);
附加调试器可以看到在下面的行中发生了段错误
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400521 in convertString (input=0x7fffffffd100 "abcdefg", output=0x7fffffffd0f0) at program.c:9
9 **output = *input;
(gdb) s
#include<stdio.h>
#include<string.h>
void convertString(char *input, char **output)
{
if(strlen(input)== 0)
{
return;
}
**output = *input;
(*output)++;
convertString(input+1,output);
}
int main()
{
char input[] = "abcdefg";
char output[sizeof(input)];
convertString(input, &output);
printf("%s", output);
return 0;
}
请帮助我在哪里做错了。
答案 0 :(得分:5)
问题是output
不是指针,它是一个数组,并且在数组上使用address-of运算符为您提供了一个指向数组的(单个)指针(在您的类型{{1]的情况下}})。为了澄清:char (*)[8]
,数组的衰减指针和指向数组的指针都是相等的。
所以你并没有真正地将指针传递给指向(void *) output == (void *) &output
函数的指针。
除了上面的内容之外,我认为函数不应该使用指向指针的指针,普通的单指针就足够了。否则,在char
调用中使用output
时会出现错误结果,因为printf
会超出字符串的结尾。
此外,您不会终止output
字符串。
答案 1 :(得分:3)
这里你真的不需要一个指向输出缓冲区的双指针,一个普通的char*
就足够了:
#include<stdio.h>
#include<string.h>
void convertString(char *input, char *output)
{
if(!(*output = *input)) // Copy the zero terminator as well.
return;
convertString(input + 1, output + 1);
}
int main()
{
char input[] = "abcdefg";
char output[sizeof(input)];
convertString(input, output);
printf("%s", output);
return 0;
}
答案 2 :(得分:3)
字符数组output
的类型char [sizeof( "abcdefg" ) ]
等同于char[8]
。所以在函数调用中表达&output
convertString(input, &output);
具有类型char ( * )[8]
,而函数的相应参数具有类型char **
。它们是不兼容的类型,编译器指出了这个错误。
将此参数声明为类型char **
是没有意义的。它必须声明为char *
。
void convertString(char *input, char *output);
同样在函数内,终止零不会从输入字符串复制到输出字符串。该功能只是退出。
if(strlen(input)== 0)
{
return;
}
在每次递归中计算字符串的长度是低效的。您至少可以替换此条件
if ( input[0] == '\0' )
或
if ( *input == '\0' )
或
if ( !*input )
还不清楚为什么函数名为convertString
而不是copyString
。
考虑到一个常见的约定,即字符串函数返回指向它们处理的字符串的指针。 可以更简单地定义函数。
这是一个示范程序
#include <stdio.h>
char * copyString( char *output, const char *input )
{
if ( ( *output = *input ) ) copyString( output + 1, input + 1 );
return output;
}
int main(void)
{
char input[] = "abcdefg";
char output[sizeof(input)];
puts( copyString( output, input ) );
return 0;
}
程序输出
abcdefg
答案 3 :(得分:-1)
正如Mr. JP his answer中docs所指出的那样,问题是&output
char **
没有给你char (*)[8]
,它给出了char *
case,当用作函数参数时将衰减为void convertString(char *input, char **output)
。
在您的情况下,您不需要指向指针来改变该指针指向的内存区域的内容。一个简单的指针就可以了。你可以改变
void convertString(char *input, char *output) //output is of type char*
到
output
和convertString(input, output);
的其他事件类似,并将其称为
output
应该有用。
也就是说,你应该将normed
空终止,使其用作字符串。
答案 4 :(得分:-1)
#include<stdio.h>
#include<string.h>
void convertString(char *input, char *output)
{
if(strlen(input)== 0)
{
return;
}
*output = *input;
output++;
convertString(input+1,output);
}
int main()
{
char input[] = "abcdefg";
char output[sizeof(input)];
convertString(input, output);
printf("%s\n", output);
return 0;
}
这可能是你想做的?