Lably
Skip to content

Function pointer

  • 20 min read
  • 5 chapters

Related on Lably

Through Function (computer programming), Programming language generations and COBOL

Function pointers allow different code to be executed at runtime. They can also be passed to a function to enable callbacks.

Function pointers are supported by third-generation programming languages (such as PL/I, COBOL, Fortran, dBASE dBL, and C) and object-oriented programming languages (such as C++, C#, and D).

Simple function pointers

The simplest implementation of a function (or subroutine) pointer is as a variable containing the address of the function within executable memory. Older third-generation languages such as PL/I and COBOL, as well as more modern languages such as Pascal and C generally implement function pointers in this manner.

Example in C

The following C program illustrates the use of two function pointers:

  • func1 takes one double-precision (double) parameter and returns another double, and is assigned to a function which converts centimeters to inches.
  • func2 takes a pointer to a constant character array as well as an integer and returns a pointer to a character, and is assigned to a C string handling function which returns a pointer to the first occurrence of a given character in a character array.
<span id="mwOw"></span><span class="cp" id="mwPA">#include</span><span class="w" id="mwPQ"> </span><span class="cpf" id="mwPg"><stdio.h></span><span class="c1" id="mwPw"> /* for printf */</span> <span class="cp" id="mwQA">#include</span><span class="w" id="mwQQ"> </span><span class="cpf" id="mwQg"><string.h></span><span class="c1" id="mwQw"> /* for strchr */</span> <span class="kt" id="mwRA">double</span><span class="w" id="mwRQ"> </span><span class="nf" id="mwRg">cm_to_inches</span><span class="p" id="mwRw">(</span><span class="kt" id="mwSA">double</span><span class="w" id="mwSQ"> </span><span class="n" id="mwSg">cm</span><span class="p" id="mwSw">)</span><span class="w" id="mwTA"> </span><span class="p" id="mwTQ">{</span> <span class="w" id="mwTg"> </span><span class="k" id="mwTw">return</span><span class="w" id="mwUA"> </span><span class="n" id="mwUQ">cm</span><span class="w" id="mwUg"> </span><span class="o" id="mwUw">/</span><span class="w" id="mwVA"> </span><span class="mf" id="mwVQ">2.54</span><span class="p" id="mwVg">;</span> <span class="p" id="mwVw">}</span> <span class="c1" id="mwWA">// "strchr" is part of the C string handling (i.e., no need for declaration)</span> <span class="c1" id="mwWQ">// See https://en.wikipedia.org/wiki/C_string_handling#Functions</span> <span class="kt" id="mwWg">int</span><span class="w" id="mwWw"> </span><span class="nf" id="mwXA">main</span><span class="p" id="mwXQ">(</span><span class="kt" id="mwXg">void</span><span class="p" id="mwXw">)</span><span class="w" id="mwYA"> </span><span class="p" id="mwYQ">{</span> <span class="w" id="mwYg"> </span><span class="kt" id="mwYw">double</span><span class="w" id="mwZA"> </span><span class="p" id="mwZQ">(</span><span class="o" id="mwZg">*</span><span class="n" id="mwZw">func1</span><span class="p" id="mwaA">)(</span><span class="kt" id="mwaQ">double</span><span class="p" id="mwag">)</span><span class="w" id="mwaw"> </span><span class="o" id="mwbA">=</span><span class="w" id="mwbQ"> </span><span class="n" id="mwbg">cm_to_inches</span><span class="p" id="mwbw">;</span> <span class="w" id="mwcA"> </span><span class="kt" id="mwcQ">char</span><span class="w" id="mwcg"> </span><span class="o" id="mwcw">*</span><span class="w" id="mwdA"> </span><span class="p" id="mwdQ">(</span><span class="o" id="mwdg">*</span><span class="n" id="mwdw">func2</span><span class="p" id="mweA">)(</span><span class="k" id="mweQ">const</span><span class="w" id="mweg"> </span><span class="kt" id="mwew">char</span><span class="w" id="mwfA"> </span><span class="o" id="mwfQ">*</span><span class="p" id="mwfg">,</span><span class="w" id="mwfw"> </span><span class="kt" id="mwgA">int</span><span class="p" id="mwgQ">)</span><span class="w" id="mwgg"> </span><span class="o" id="mwgw">=</span><span class="w" id="mwhA"> </span><span class="n" id="mwhQ">strchr</span><span class="p" id="mwhg">;</span> <span class="w" id="mwhw"> </span><span class="n" id="mwiA">printf</span><span class="p" id="mwiQ">(</span><span class="s" id="mwig">"%f %s"</span><span class="p" id="mwiw">,</span><span class="w" id="mwjA"> </span><span class="n" id="mwjQ">func1</span><span class="p" id="mwjg">(</span><span class="mf" id="mwjw">15.0</span><span class="p" id="mwkA">),</span><span class="w" id="mwkQ"> </span><span class="n" id="mwkg">func2</span><span class="p" id="mwkw">(</span><span class="s" id="mwlA">"Wikipedia"</span><span class="p" id="mwlQ">,</span><span class="w" id="mwlg"> </span><span class="sc" id="mwlw">'p'</span><span class="p" id="mwmA">));</span> <span class="w" id="mwmQ"> </span><span class="cm" id="mwmg">/* prints "5.905512 pedia" */</span> <span class="w" id="mwmw"> </span><span class="k" id="mwnA">return</span><span class="w" id="mwnQ"> </span><span class="mi" id="mwng">0</span><span class="p" id="mwnw">;</span> <span class="p" id="mwoA">}</span>

The next program uses a function pointer to invoke one of two functions (sin or cos) indirectly from another function (compute_sum, computing an approximation of the function's Riemann integration). The program operates by having function main call function compute_sum twice, passing it a pointer to the library function sin the first time, and a pointer to function cos the second time. Function compute_sum in turn invokes one of the two functions indirectly by dereferencing its function pointer argument funcp multiple times, adding together the values that the invoked function returns and returning the resulting sum. The two sums are written to the standard output by main.

<span id="mwrw"></span><span class="linenos" data-line="1" id="mwsA"></span><span class="cp" id="mwsQ">#include</span><span class="w" id="mwsg"> </span><span class="cpf" id="mwsw"><math.h></span> <span class="linenos" data-line="2" id="mwtA"></span><span class="cp" id="mwtQ">#include</span><span class="w" id="mwtg"> </span><span class="cpf" id="mwtw"><stdio.h></span> <span class="linenos" data-line="3" id="mwuA"></span> <span class="linenos" data-line="4" id="mwuQ"></span><span class="c1" id="mwug">// Function taking a function pointer as an argument</span> <span class="linenos" data-line="5" id="mwuw"></span><span class="kt" id="mwvA">double</span><span class="w" id="mwvQ"> </span><span class="nf" id="mwvg">compute_sum</span><span class="p" id="mwvw">(</span><span class="kt" id="mwwA">double</span><span class="w" id="mwwQ"> </span><span class="p" id="mwwg">(</span><span class="o" id="mwww">*</span><span class="n" id="mwxA">funcp</span><span class="p" id="mwxQ">)(</span><span class="kt" id="mwxg">double</span><span class="p" id="mwxw">),</span><span class="w" id="mwyA"> </span><span class="kt" id="mwyQ">double</span><span class="w" id="mwyg"> </span><span class="n" id="mwyw">lo</span><span class="p" id="mwzA">,</span><span class="w" id="mwzQ"> </span><span class="kt" id="mwzg">double</span><span class="w" id="mwzw"> </span><span class="n" id="mw0A">hi</span><span class="p" id="mw0Q">)</span><span class="w" id="mw0g"> </span><span class="p" id="mw0w">{</span> <span class="linenos" data-line="6" id="mw1A"></span><span class="w" id="mw1Q"> </span><span class="kt" id="mw1g">double</span><span class="w" id="mw1w"> </span><span class="n" id="mw2A">sum</span><span class="w" id="mw2Q"> </span><span class="o" id="mw2g">=</span><span class="w" id="mw2w"> </span><span class="mf" id="mw3A">0.0</span><span class="p" id="mw3Q">;</span> <span class="linenos" data-line="7" id="mw3g"></span> <span class="linenos" data-line="8" id="mw3w"></span><span class="w" id="mw4A"> </span><span class="c1" id="mw4Q">// Add values returned by the pointed-to function '*funcp'</span> <span class="linenos" data-line="9" id="mw4g"></span><span class="w" id="mw4w"> </span><span class="kt" id="mw5A">int</span><span class="w" id="mw5Q"> </span><span class="n" id="mw5g">i</span><span class="p" id="mw5w">;</span> <span class="linenos" data-line="10" id="mw6A"></span><span class="w" id="mw6Q"> </span><span class="k" id="mw6g">for</span><span class="w" id="mw6w"> </span><span class="p" id="mw7A">(</span><span class="n" id="mw7Q">i</span><span class="w" id="mw7g"> </span><span class="o" id="mw7w">=</span><span class="w" id="mw8A"> </span><span class="mi" id="mw8Q">0</span><span class="p" id="mw8g">;</span><span class="w" id="mw8w"> </span><span class="n" id="mw9A">i</span><span class="w" id="mw9Q"> </span><span class="o" id="mw9g"><=</span><span class="w" id="mw9w"> </span><span class="mi" id="mw-A">100</span><span class="p" id="mw-Q">;</span><span class="w" id="mw-g"> </span><span class="n" id="mw-w">i</span><span class="o" id="mw_A">++</span><span class="p" id="mw_Q">)</span><span class="w" id="mw_g"> </span><span class="p" id="mw_w">{</span> <span class="linenos" data-line="11" id="mwAQA"></span><span class="w" id="mwAQE"> </span><span class="c1" id="mwAQI">// Use the function pointer 'funcp' to invoke the function</span> <span class="linenos" data-line="12" id="mwAQM"></span><span class="w" id="mwAQQ"> </span><span class="kt" id="mwAQU">double</span><span class="w" id="mwAQY"> </span><span class="n" id="mwAQc">x</span><span class="w" id="mwAQg"> </span><span class="o" id="mwAQk">=</span><span class="w" id="mwAQo"> </span><span class="n" id="mwAQs">i</span><span class="w" id="mwAQw"> </span><span class="o" id="mwAQ0">/</span><span class="w" id="mwAQ4"> </span><span class="mf" id="mwAQ8">100.0</span><span class="w" id="mwARA"> </span><span class="o" id="mwARE">*</span><span class="w" id="mwARI"> </span><span class="p" id="mwARM">(</span><span class="n" id="mwARQ">hi</span><span class="w" id="mwARU"> </span><span class="o" id="mwARY">-</span><span class="w" id="mwARc"> </span><span class="n" id="mwARg">lo</span><span class="p" id="mwARk">)</span><span class="w" id="mwARo"> </span><span class="o" id="mwARs">+</span><span class="w" id="mwARw"> </span><span class="n" id="mwAR0">lo</span><span class="p" id="mwAR4">;</span> <span class="linenos" data-line="13" id="mwAR8"></span><span class="w" id="mwASA"> </span><span class="kt" id="mwASE">double</span><span class="w" id="mwASI"> </span><span class="n" id="mwASM">y</span><span class="w" id="mwASQ"> </span><span class="o" id="mwASU">=</span><span class="w" id="mwASY"> </span><span class="n" id="mwASc">funcp</span><span class="p" id="mwASg">(</span><span class="n" id="mwASk">x</span><span class="p" id="mwASo">);</span> <span class="linenos" data-line="14" id="mwASs"></span><span class="w" id="mwASw"> </span><span class="n" id="mwAS0">sum</span><span class="w" id="mwAS4"> </span><span class="o" id="mwAS8">+=</span><span class="w" id="mwATA"> </span><span class="n" id="mwATE">y</span><span class="p" id="mwATI">;</span> <span class="linenos" data-line="15" id="mwATM"></span><span class="w" id="mwATQ"> </span><span class="p" id="mwATU">}</span> <span class="linenos" data-line="16" id="mwATY"></span><span class="w" id="mwATc"> </span><span class="k" id="mwATg">return</span><span class="w" id="mwATk"> </span><span class="n" id="mwATo">sum</span><span class="w" id="mwATs"> </span><span class="o" id="mwATw">/</span><span class="w" id="mwAT0"> </span><span class="mf" id="mwAT4">101.0</span><span class="w" id="mwAT8"> </span><span class="o" id="mwAUA">*</span><span class="w" id="mwAUE"> </span><span class="p" id="mwAUI">(</span><span class="n" id="mwAUM">hi</span><span class="w" id="mwAUQ"> </span><span class="o" id="mwAUU">-</span><span class="w" id="mwAUY"> </span><span class="n" id="mwAUc">lo</span><span class="p" id="mwAUg">);</span> <span class="linenos" data-line="17" id="mwAUk"></span><span class="p" id="mwAUo">}</span> <span class="linenos" data-line="18" id="mwAUs"></span> <span class="linenos" data-line="19" id="mwAUw"></span><span class="kt" id="mwAU0">double</span><span class="w" id="mwAU4"> </span><span class="nf" id="mwAU8">square</span><span class="p" id="mwAVA">(</span><span class="kt" id="mwAVE">double</span><span class="w" id="mwAVI"> </span><span class="n" id="mwAVM">x</span><span class="p" id="mwAVQ">)</span><span class="w" id="mwAVU"> </span><span class="p" id="mwAVY">{</span> <span class="linenos" data-line="20" id="mwAVc"></span><span class="w" id="mwAVg"> </span><span class="k" id="mwAVk">return</span><span class="w" id="mwAVo"> </span><span class="n" id="mwAVs">x</span><span class="w" id="mwAVw"> </span><span class="o" id="mwAV0">*</span><span class="w" id="mwAV4"> </span><span class="n" id="mwAV8">x</span><span class="p" id="mwAWA">;</span> <span class="linenos" data-line="21" id="mwAWE"></span><span class="p" id="mwAWI">}</span> <span class="linenos" data-line="22" id="mwAWM"></span> <span class="linenos" data-line="23" id="mwAWQ"></span><span class="kt" id="mwAWU">int</span><span class="w" id="mwAWY"> </span><span class="nf" id="mwAWc">main</span><span class="p" id="mwAWg">(</span><span class="kt" id="mwAWk">void</span><span class="p" id="mwAWo">)</span><span class="w" id="mwAWs"> </span><span class="p" id="mwAWw">{</span> <span class="linenos" data-line="24" id="mwAW0"></span><span class="w" id="mwAW4"> </span><span class="kt" id="mwAW8">double</span><span class="w" id="mwAXA"> </span><span class="n" id="mwAXE">sum</span><span class="p" id="mwAXI">;</span> <span class="linenos" data-line="25" id="mwAXM"></span> <span class="linenos" data-line="26" id="mwAXQ"></span><span class="w" id="mwAXU"> </span><span class="c1" id="mwAXY">// Use standard library function 'sin()' as the pointed-to function</span> <span class="linenos" data-line="27" id="mwAXc"></span><span class="w" id="mwAXg"> </span><span class="n" id="mwAXk">sum</span><span class="w" id="mwAXo"> </span><span class="o" id="mwAXs">=</span><span class="w" id="mwAXw"> </span><span class="n" id="mwAX0">compute_sum</span><span class="p" id="mwAX4">(</span><span class="n" id="mwAX8">sin</span><span class="p" id="mwAYA">,</span><span class="w" id="mwAYE"> </span><span class="mf" id="mwAYI">0.0</span><span class="p" id="mwAYM">,</span><span class="w" id="mwAYQ"> </span><span class="mf" id="mwAYU">1.0</span><span class="p" id="mwAYY">);</span> <span class="linenos" data-line="28" id="mwAYc"></span><span class="w" id="mwAYg"> </span><span class="n" id="mwAYk">printf</span><span class="p" id="mwAYo">(</span><span class="s" id="mwAYs">"sum(sin): %g</span><span class="se" id="mwAYw">\n</span><span class="s" id="mwAY0">"</span><span class="p" id="mwAY4">,</span><span class="w" id="mwAY8"> </span><span class="n" id="mwAZA">sum</span><span class="p" id="mwAZE">);</span> <span class="linenos" data-line="29" id="mwAZI"></span> <span class="linenos" data-line="30" id="mwAZM"></span><span class="w" id="mwAZQ"> </span><span class="c1" id="mwAZU">// Use standard library function 'cos()' as the pointed-to function</span> <span class="linenos" data-line="31" id="mwAZY"></span><span class="w" id="mwAZc"> </span><span class="n" id="mwAZg">sum</span><span class="w" id="mwAZk"> </span><span class="o" id="mwAZo">=</span><span class="w" id="mwAZs"> </span><span class="n" id="mwAZw">compute_sum</span><span class="p" id="mwAZ0">(</span><span class="n" id="mwAZ4">cos</span><span class="p" id="mwAZ8">,</span><span class="w" id="mwAaA"> </span><span class="mf" id="mwAaE">0.0</span><span class="p" id="mwAaI">,</span><span class="w" id="mwAaM"> </span><span class="mf" id="mwAaQ">1.0</span><span class="p" id="mwAaU">);</span> <span class="linenos" data-line="32" id="mwAaY"></span><span class="w" id="mwAac"> </span><span class="n" id="mwAag">printf</span><span class="p" id="mwAak">(</span><span class="s" id="mwAao">"sum(cos): %g</span><span class="se" id="mwAas">\n</span><span class="s" id="mwAaw">"</span><span class="p" id="mwAa0">,</span><span class="w" id="mwAa4"> </span><span class="n" id="mwAa8">sum</span><span class="p" id="mwAbA">);</span> <span class="linenos" data-line="33" id="mwAbE"></span> <span class="linenos" data-line="34" id="mwAbI"></span><span class="w" id="mwAbM"> </span><span class="c1" id="mwAbQ">// Use user-defined function 'square()' as the pointed-to function</span> <span class="linenos" data-line="35" id="mwAbU"></span><span class="w" id="mwAbY"> </span><span class="n" id="mwAbc">sum</span><span class="w" id="mwAbg"> </span><span class="o" id="mwAbk">=</span><span class="w" id="mwAbo"> </span><span class="n" id="mwAbs">compute_sum</span><span class="p" id="mwAbw">(</span><span class="n" id="mwAb0">square</span><span class="p" id="mwAb4">,</span><span class="w" id="mwAb8"> </span><span class="mf" id="mwAcA">0.0</span><span class="p" id="mwAcE">,</span><span class="w" id="mwAcI"> </span><span class="mf" id="mwAcM">1.0</span><span class="p" id="mwAcQ">);</span> <span class="linenos" data-line="36" id="mwAcU"></span><span class="w" id="mwAcY"> </span><span class="n" id="mwAcc">printf</span><span class="p" id="mwAcg">(</span><span class="s" id="mwAck">"sum(square): %g</span><span class="se" id="mwAco">\n</span><span class="s" id="mwAcs">"</span><span class="p" id="mwAcw">,</span><span class="w" id="mwAc0"> </span><span class="n" id="mwAc4">sum</span><span class="p" id="mwAc8">);</span> <span class="linenos" data-line="37" id="mwAdA"></span> <span class="linenos" data-line="38" id="mwAdE"></span><span class="w" id="mwAdI"> </span><span class="k" id="mwAdM">return</span><span class="w" id="mwAdQ"> </span><span class="mi" id="mwAdU">0</span><span class="p" id="mwAdY">;</span> <span class="linenos" data-line="39" id="mwAdc"></span><span class="p" id="mwAdg">}</span>

Sign in to keep reading

4 more chapters are free with a Lably account.

More in Computing and communication