c# 中代替指针的功能

A function pointer in C is a pointer that points to a function.

C语言中的函数指针是指向函数的指针

The C language has given a way for us to making certain statements execute faster, by allowing us to reference executable code within a function.

通过允许我们在函数中引用可执行代码,C语言为我们提供了一种使某些语句更快执行的方法。

This reference involves the function pointer, which points to this code in memory (RAM).

该引用涉及函数指针,该指针指向内存( RAM )中的此代码。

Since we’re calling this function through a variable, such a call is called an indirect call to this function.

由于我们通过变量调用此函数,因此这种调用称为对此函数的间接调用

Let’s understand this, by illustrating how this reference is made to a simple swap() function.

让我们通过说明如何对简单的swap()函数进行引用来了解这一点。

C Swap Function Reference Asm
C交换功能参考汇编

If we were to make a function pointer that references the swap() function, it will point to the executable code, which is shown in the assembly language.

如果我们要创建一个引用swap()函数的函数指针,它将指向可执行代码,该代码以汇编语言显示。

This will make the overall execution speed much faster, since we directly refer to a lower level code.

因为我们直接引用了较低级别的代码,所以这将使整体执行速度更快。

Now that we have our concepts covered, let’s look at how we can actually write a function pointer for our swap function.

现在我们已经涵盖了概念,让我们看一下如何为交换函数实际编写函数指针。



定义功能指针 (Defining a Function Pointer)

Before defining the function pointer, let’s break down what any function consists of.

在定义函数指针之前,让我们分解一下任何函数组成的内容。

Any function will have a return type, arguments passed to it, and a name, such as:

任何函数都将具有返回类型,传递给它的参数和名称,例如:


int function_name(char arg1, int arg2);

The function pointer simply points to such a function, so we can define a function pointer like this:

函数指针仅指向此类函数,因此我们可以定义如下函数指针:


int (*function_ptr)(char, char);

This says that function_ptr is a function pointer which points to a function that takes 2 char arguments and returns an int.

这表示function_ptr是一个函数指针,指向一个带有2个char参数并返回int的函数。

Notice the enclosing parenthesis (*function_ptr). This is because we must explicitly specify that it is a pointer. Otherwise, the compiler may think that we are pointing to a function that returns int* and throw an error.

请注意括号(* function_ptr) 。 这是因为我们必须明确指定它是一个指针。 否则,编译器可能会认为我们指向的是一个返回int *并抛出错误的函数。

Similarly, for a function that is defined like this:

类似地,对于这样定义的函数:


char* str_concat(char* a, char* b);

The function pointer is defined in this way:

函数指针的定义方式如下:


char* (*function_ptr_2)(char*, char*);

Now that we’ve defined our function pointers, let’s now make a reference to the functions, by pointing to the function name.

现在我们已经定义了函数指针,现在让我们通过指向函数名称来引用函数。


function_ptr = &function_name;
function_ptr_2 = &str_concat;

Note that you don’t need to explicitly mention the referencing ampersand (&), since functions are implicitly passed as pointers anyway, so the following code is still valid.

请注意,由于函数无论如何都隐式地作为指针传递,因此您无需显式提及引用“& ”号 ,因此以下代码仍然有效。


function_ptr = function_name;
function_ptr_2 = str_concat;

直接初始化 (Direct Initialization)

Alternatively, we can directly point to the function during declaration itself, like any other pointer.

另外,我们可以像其他任何指针一样直接在声明过程中指向该函数。


int (*function_ptr)(char, char) = function_name;
char* (*function_ptr_2)(char*, char*) = str_concat;

Now that we’ve looked at initializing the pointer, let’s now see it in action!

现在,我们已经着手初始化指针,现在让我们看看它的实际作用!



使用功能指针 (Using Function Pointers)

This is really simple! We just need to de-reference our function pointer by passing appropriate arguments, and it will run the executable code which it is pointing to. That’s it!

这真的很简单! 我们只需要通过传递适当的参数来取消引用我们的函数指针,它将运行它所指向的可执行代码。 而已!


return_value = (*function_ptr)(arg1, arg2);

Again, you don’t need to explicitly mention the de-referencing asterisk (*), since functions are implicitly passed as pointers anyway. But if you do, you must explicitly mention the parenthesis (*function_ptr)(arg1, arg2), since a function call has a higher precedence over a de-reference.

同样,您无需显式提及取消引用星号(*),因为无论如何函数都是作为指针隐式传递的。 但是,如果这样做,则必须明确提及括号(* function_ptr)(arg1,arg2) ,因为函数调用的优先级高于取消引用。


return_value = function_ptr(arg1, arg2);

If the function takes no arguments, you can pass void to the parameter list.

如果函数不带参数,则可以将void传递给参数列表。

Let’s do this for our swap() function.

让我们为swap()函数执行此操作。


#include <stdio.h>void swap(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}int main() {int a = 20;int b = 10;// swap(&a, &amp;b);// Using function pointersvoid (*swap_ptr)(int*, int*) = swap;printf("Dereferencing the function pointer...\n");swap_ptr(&a, &amp;b);printf("a = %d, b = %d\n", a, b);return 0;
}


另一个例子 (Another Example)

To complete this article, we’ll show you a complete example.

为了完成本文,我们将向您展示一个完整的示例。

This is a simple calculator program that utilizes function pointers to handle cases easily. Elegant, isn’t it?

这是一个简单的计算器程序,利用函数指针轻松处理个案。 优雅,不是吗?


#include <stdio.h>double add(double a, double b) {return a + b;
}double sub (double a, double b) {return a - b;
}double mul(double a, double b) {return a * b;
}double div (double a, double b) {return a / b;
}double zero(double a, double b) {return 0.0;
}double calculator(double a, double b, char option) {double result = 0.0;double (*funct_ptr)(double, double);if (option == 'A')funct_ptr = add;else if (option == 'S')funct_ptr = sub;else if (option == 'M')funct_ptr = mul;else if (option == 'D')funct_ptr = div;elsefunct_ptr = zero;result = funct_ptr(a, b);return result;
}int main() {printf("%lf\n", calculator(10, 5, 'A'));printf("%lf\n", calculator(10, 5, 'S'));printf("%lf\n", calculator(10, 5, 'M'));printf("%lf\n", calculator(10, 5, 'D'));return 0;
}

Output

输出量


15.000000
5.000000
50.000000
2.000000

Another way to make a function pointer point to multiple other function codes is with the use of a function pointer array. Have a look at the sample code below.

使功能指针指向多个其他功能代码的另一种方法是使用功能指针数组 。 看看下面的示例代码。


#include <stdio.h>double add(double a, double b) {return a + b;
}
double sub (double a, double b) {return a - b;
}
double mul(double a, double b) {return a * b;
}
double div (double a, double b) {return a / b;
}
double zero(double a, double b) {return 0.0;
}int main() {double (*funct_ptr[])(double, double)={add,sub,mul,div};printf("%lf\n", funct_ptr[0](5,6));printf("%lf\n", funct_ptr[1](5,6));printf("%lf\n", funct_ptr[2](5,6));printf("%lf\n", funct_ptr[3](5,6));return 0;
}

11.000000
-1.000000
30.000000
0.833333


结论 (Conclusions)

Hopefully, you’ve learned how you can use a function pointer in C. If you have any queries, do ask them on the comment section below!

希望您已经学会了如何在C语言中使用函数指针。如果您有任何疑问,请在下面的注释部分提问!



参考资料 (References)

  • Wikipedia article on Function Pointer维基百科有关函数指针的文章
  • CMU Lecture Notes on Function Pointers (Recommended Read. You can attempt some of the exercises.)CMU功能指针讲义 (推荐阅读。您可以尝试一些练习。)
  • Related StackOverflow question相关StackOverflow问题


翻译自: https://www.journaldev.com/35758/function-pointer-in-c

c# 中代替指针的功能

c# 中代替指针的功能_C中的功能指针相关推荐

  1. c6011取消对null指针的引用_C++中的野指针及其规避方法

    今天在调试程序过程中,用到了一些指针的方法,这里记录一下野指针的概念. 1.概念 野指针,也就是指向不可用内存区域的指针.通常对这种指针进行操作的话,将会使程序发生不可预知的错误. 野指针与空指针(N ...

  2. c6011取消对null指针的引用_C++中的引用

    当变量声明为引用时,它将成为现有变量的替代名称.通过在声明中添加"&",可以将变量声明为引用. #include using namespace std; int main ...

  3. c语言中浮点数和整数转换_C中的数据类型-整数,浮点数和空隙说明

    c语言中浮点数和整数转换 C中的数据类型 (Data Types in C) There are several different ways to store data in C, and they ...

  4. c6011取消对null指针的引用_C++| 函数的指针参数如何传递内存?

    函数的参数是一个一级指针,可以传递内存吗? 如果函数的参数是一个一级指针,不要指望用该指针去申请动态内存. 看下面的实例: #include using namespace std; void Get ...

  5. blt功能_C++中BitBlt的使用方法详解

    BitBlt 该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境. 原型: BOOL BitBlt( HDC hdcDest, int nXDest, int ...

  6. [转载] c语言中检查命令行参数_C中的命令行参数

    参考链接: Java中的命令行参数 c语言中检查命令行参数 Command line argument is a parameter supplied to the program when it i ...

  7. python中data是什么意思_C++中cv::Mat中的data属性对应在python中是什么

    1, 因为我要使用一个dll,看C++的代码,是这样调用的 using namespace cv; m_image_mat = imread ( full_file_name ); data = m_ ...

  8. c++成员声明中的非法限定名_C++中作用域限定符

    在不同作用域内声明的变量可以同名,但如果局部变量和全局变量同名,在局部变量作用域内如何访问全局变量?C语言没有提供同名情况下访问全局变量的方法.在C++中,可以通过使用作用域限定符(::)(scope ...

  9. c语言指针官方解释_C语言中的指针解释了–它们并不像您想象的那么难

    c语言指针官方解释 Pointers are arguably the most difficult feature of C to understand. But, they are one of ...

最新文章

  1. 直流电路相关计算机,计算机专业用复杂直流电路习题(各种方法运用).doc
  2. DRX不连续接收(1)
  3. 失败如何助你升入最高管理层
  4. ASP.Net中实现中英文复合检索文本框
  5. 阿里云不做SaaS、要练好内功被集成,发布SaaS加速器
  6. 分布式任务调度平台XXL-JOB搭建使用
  7. 【Swing/文本组件】定义自动换行的文本域
  8. java数组查找文本_基于数组的二叉查找树 Binary Search Tree (Java实现)
  9. 基于SSM+SpringBoot+Vue的高校竞赛赛事管理系统
  10. 造成错误“ORA-12547: TNS:lost contact”的常见原因有哪些?
  11. 再掀融资潮 团购网仍后劲不足(团购现状分析)
  12. Java开发工程师应届生春招秋招总结
  13. 习题6-8 单词首字母大写 (15 分)
  14. Websocket(二)-客户端与服务器通信
  15. 【白嫖系列】教育邮箱申请最新专业绘图软件OriginPro(官方渠道)
  16. 【Simulink】数字控制振荡器 NCO ( N umerically CONtrolled Oscillator )
  17. Java写时复制CopyOnWriteArrayList
  18. Eclipse开发工具--简介
  19. ABAP其他基本语法
  20. seo优化需要c语言吗,SEO优化人员需要优化哪些代码?

热门文章

  1. Android - 文字中显示图片
  2. mac中强大的快捷键
  3. vs2010编译curl为static库及测试
  4. Android ViewPager 里有子ViewPager的事件冲突
  5. QQ抢车位外挂(起始篇)--小研究成果展示
  6. 数据结构与算法(Python)第一天
  7. 【7.1】property动态属性
  8. HDU 5729 Rigid Frameworks (联通块计数问题)
  9. 详解python 字符串
  10. WOE(weight of evidence, 证据权重)