我正在阅读K& R的“C编程语言”,并且我无法理解指向函数的指针的概念。为了解释函数的指针,它以程序为例,如果给出了可选参数-n,程序将以数字方式对输入行进行排序,而不是按字典顺序排序。这是程序:
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* max #lines to be sorted */
char *lineptr[MAXLINES]; /* pointers to text lines */
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *));
int numcmp(char *, char *);
/*sort input lines */
main(int argc, char *argv[])
{
int nlines; /*number of input lines read */
int numeric =0; /* 1 if numeric sort */
if (argc>1 && strcmp(argv[1], "-n")==0)
numeric=1;
if ((nlines= readlines(lineptr, MAXLINES))>=0)
{
qsort((void **) lineptr,0,nlines-1, ***(int (*)(void*,void*))(numeric?numcmp:strcmp));***
writelines(lineptr, nlines);
return 0;
}
else
{
printf("input too big to sort\n");
return 1;
}
}
我的问题是:
1)在对qsort的调用中,为什么没有传递类型为void *的参数(在粗体和斜体部分中)?
2)在对qsort的调用中(在粗体和斜体部分中),那是什么(*)单独执行,它取消引用的函数在哪里?
有人可以澄清我的怀疑。
答案 0 :(得分:2)
当您致电qsort
时,您只将指针传递给函数,您不会调用该函数本身。对numeric
或strcmp
的调用发生在qsort
函数内(您不应自行声明,而是包含<stdlib.h>
,如this qsort
reference所示,如果&qsort
#39; s您正在呼叫的标准#include <stdio.h>
void hello(const char *name)
{
printf("Hello %s\n", name);
}
void get_name_and_greet(void (*hello_function)(const char *))
{
char name[256];
printf("Please enter name: ");
scanf("%255s", name);
hello_function(name); // Use the function pointer
}
int main(void)
{
get_name_and_greet(&hello); // Pass a pointer to the function
}
。
为了更好地解释它,让我们制作一个小例子程序,展示如何使用和调用函数指针:
int
如您所见,将指针传递给函数与将指针传递给get_name_and_greet(hello("foo"));
变量没什么不同。
如果你这样做的话。
hello
你将调用 hello
函数,并使用get_name_and_greet
作为hello
的参数返回。这当然不起作用,因为(int (*)(void*,void*))
没有返回任何内容,并且会导致编译错误。
至于:host /deep/ :not(.mat-focused) .mat-input-placeholder.mat-empty {
color: transparent;
}
:host /deep/ :not(.mat-focused) .mat-input-placeholder.mat-empty::before {
content: "My custom placeholder";
color: black;
}
部分,它是一个简单的类型转换。
答案 1 :(得分:1)
至于回答你的问题1.和2.我认为你可以从阅读螺旋规则中受益:
http://c-faq.com/decl/spiral.anderson.html。
将看似复杂的C语句(如函数指针)翻译成简单的英语会很有帮助:
void qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *));
&#39;的qsort&#39;是一个带有四个参数的函数,返回void
参数0 - lineptr
- 一个void指针数组。
参数1 - left
- 一个int。
参数2 - right
- 一个int。
参数3 - comp
- 一个指向函数的指针,该函数接受两个参数,每个参数都是一个void指针,并返回一个int。
然后在打电话给&#39; qsort&#39;:
qsort((void **) lineptr,0,nlines-1, (int (*)(void*,void*))(numeric?numcmp:strcmp));
您提供了这些必要的参数,更具体地说,让我们看看第三个参数:
(int (*)(void*,void*))(numeric?numcmp:strcmp)
最后一个括号评估为&#39; numcmp&#39;或者&#39; stcmp&#39;。在任何一种情况下,这都是一个返回int的函数,唯一的区别是传入的参数的数据类型。不失一般性,让我们选择“numcmp&#39;。
那么我们就有了:
(int (*)(void*,void*))(numcmp)
我们在&#39; numcmp&#39;的左侧有什么?然后是一个演员,它负责处理函数&#39; numcmp&#39;之间的参数的数据类型的差异。和&#39; strcmp&#39;。在K&amp; R2中,它实际上解释了这一点:
&#34;函数参数的精细演员强制转换了比较函数的参数。这些通常对实际表示没有影响,但保证编译器一切正常。&#34;
此外,&#39; stcmp&#39;和&#39; numcmp&#39;是函数的地址,并且由于它们已知是函数,因此它们是函数。不需要操作员。