我想用一个指向函数的指针来反转一个String,该函数执行String的反转。我感到我没有掌握正确使用指向变量或函数的指针的概念,因此,如果有人可以解释我,我将非常感激,在这里我想错了:
1)定义函数的指针:
char *strrev(char *str)
{
char *p1, *p2;
if (! str || ! *str)
return str;
for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
{
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return str;
}
2)现在在我的主目录中定义一个指针,该指针与我上面定义的函数匹配:
int main(void) {
char (*functPtr)(char);
functPtr = &strrev;
3)现在,我定义要反转的String,定义一个新的指针,并使该指针指向String的地址空间。
char str[50] = "Hello, World";
char *pointer[50];
pointer[50] = &str[50];
4)最后,我定义一个新的String并编写该函数的结果,该结果通过指针进行调用,该指针指向该函数的指针。
char t[50] = (*functPtr)(pointer[50]);
printf("%s\n", str);
return(0);
}
不幸的是,我收到各种错误消息,例如:
Ü1.c:29:10: error: array initializer must be an initializer list or string literal
char t[50] = (*functPtr)(pointer[50]);
^
Ü1.c:27:5: warning: array index 50 is past the end of the array (which contains 50 elements) [-Warray-bounds]
pointer[50] = &str[50];
^ ~~
Ü1.c:26:5: note: array 'pointer' declared here
char *pointer[50];
^
Ü1.c:29:30: warning: array index 50 is past the end of the array (which contains 50 elements) [-Warray-bounds]
char t[50] = (*functPtr)(pointer[50]);
^ ~~
Ü1.c:26:5: note: array 'pointer' declared here
char *pointer[50];
^
2 warnings and 1 error generated.
我在此答案中总结了我的评论,因为它为评论的详细信息提供了更多的空间。
char (*functPtr)(char);
应该为char *(*functPtr)(char *);
,因为它对字符(而不是字符)使用了[[pointer。同样,它返回一个指针。
char *pointer[50];
将是50个指针的数组,您想说“指向50个字符的数组的指针”。在C语言中,我们不会这样说。我们只是说“指向char的指针”,没有说多少。因此char *pointer;
就足够了。char t[50] = (*functPtr)(pointer[50]);
在C中不正确。
您想将funcPtr
的结果分配给数组t
。但是这里您将初始化与赋值混合在一起。char t[50];
声明一个由50个字符组成的数组。您可以通过给它一个值来初始化它,例如char t[50] = "Hello World";
,它将使编译器将“ Hello World”复制到数组。
但是您尝试将函数指针分配给数组。您可能打算将函数的结果放入数组中。
也请注意,您不能将一个数组“分配”到另一个数组。您只能复制它。
所以正确的代码应该是:
char *(*functPtr)(char *);
functPtr = &strrev;
char str[50] = "Hello, World";
char t[50];
char *s= funcPtr(str); // call the function and save the returned pointer
strcpy(t, s); // now copy the result to your array.
printf("%s\n", t); // and print it
注意:char str[50] = "Hello, World";
是正确的,只是您会知道char *str = "Hello, World";
是错误的。为什么?因为第二个str
将指向只读内存(“字符串文字”),并且任何对其进行修改的尝试都将中止程序。但是这里您做对了。
1)定义函数的指针:
不,您没有定义函数指针。您定义了一个名称为strrev
的函数。
2)现在,在我的主体中定义一个指针,该指针与函数 上面定义:
int main(void) {
char *(*functPtr)(char *);
functPtr = &strrev;
是,您定义了一个函数指针,并使用函数strrev
的地址对其进行了初始化。由于表达式中使用的函数指示符被隐式转换为函数的指针,因此您可以编写
int main(void) { char *(*functPtr)(char *); functPtr = strrev;
3)现在,我定义要反转的字符串,定义一个新的 指针,并使其指向字符串的地址空间。
char str[50] = "Hello, World"; char *pointer[50]; pointer[50] = &str[50];
除了包含字符串的字符数组的定义之外,所有其他记录都没有任何意义。对于初学者,功能strrev
将字符串反过来。它不会创建传递给它的字符串的反向副本。如果要声明一个指针,该指针将获取函数返回的与原始字符串的地址相等的反向字符串的地址,则可以只写
char *pointer = functPtr( str );
4)最后,我定义一个新的String并写入函数的结果, 通过指针进行调用,该指针指向指向 功能。
char t[50] = (*functPtr)(pointer[50]); printf("%s\n", str);
您已经定义了一个指针,该指针将获取从函数返回的值。因此,没有必要再声明一个数组。此外,数组没有赋值运算符。该函数将原始字符串反转到位。为什么要使用原始反向字符串的重复副本再创建一个数组?这完全没有道理。您的程序可以通过以下方式查看
#include <stdio.h> #include <string.h> char * strrev( char *s ) { size_t n = strlen( s ); if ( n ) { for ( char *first = s, *last = s + n; first < --last; ++first ) { char c = *first; *first = *last; *last = c; } } return s; } int main(void) { char * ( *fp )( char * ) = strrev; char s[] = "Hello, World"; puts( s ); puts( fp( s ) ); return 0; }
程序输出为
Hello, World dlroW ,olleH