Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h3>No, and why not</h3> <p>To answer your question: no you can't, in the way that you are thinking (i.e. function pointer). What a function pointer is is a variable with an address of another variable. To illustrate, consider how this works when you have a function pointer <code>foo</code> pointing to function <code>bar</code>. </p> <pre><code>int bar() { } void baz(int (*foo)()) { int x = foo(); // Calls the function pointed to bar foo } int main() { int (*foo)(); foo = &amp;bar; baz(foo); // Cal baz() passing it foo, which points to bar() } </code></pre> <p>What <code>foo</code> holds is the address of <code>bar</code>. When you pass <code>foo</code> to some function that expects a function pointer parameter (in this case <code>baz()</code>), the function dereferences the pointer, i.e. looks at the memory address associated with <code>foo</code>, gets the address sored in it, in our case the the address of <code>bar</code>, and then calls a function (in our case, <code>bar</code>) at that address. To be very careful about this: in the above example <code>baz()</code> says</p> <ul> <li>Let me look at the memory associated with <code>foo</code>, it has another address in it</li> <li>Load that address from memory, and call a function at that address. That function returns an <code>int</code> and takes no parameters.</li> </ul> <p>Let's contrast this with a function that calls <code>bar()</code> directly:</p> <pre><code>void qux() { int x = bar(); // Call bar() } </code></pre> <p>In this case there is no function pointer. What there is, is an address, supplied by the linker. The linker lays out all the functions in your program, and it knows, for instance that <code>bar()</code> is at address <code>0xDEADBEEF</code>. So in <code>qux()</code> there is just a <code>jump 0xDEADBEEF</code> call. In contrast in <code>baz</code>() there is something like (pseudo-addembly):</p> <pre><code>pop bar off the stack into register A read memory address pointed to by register A into register B jump to memory location pointed to by register B </code></pre> <p>The way <code>putch()</code> gets called from <code>printf()</code>, for instance, is exactly like <code>qux()</code> calls <code>bar()</code>, and not like the way <code>baz()</code> does: <code>putch</code> gets <em>statically linked</em> into your program, so the address of <code>putch()</code> is hardcoded in there, simple because <code>fprintf()</code> doesn't take a function pointer to call for a parameter.</p> <h3>Why <code>#define</code> is not the answer</h3> <p><code>#define</code> is a <em>preprocessor</em> directive, that is, "symbols" defined with <code>#define</code> are replaced with their values before the compiler even sees your code. This means that <code>#define</code> makes your program <em>less dynamically modifiable</em> not more. This is desirable in some cases, but in your case it will not help you. To illustrate if you define a symbol like this:</p> <pre><code>#define Pi 3.14 </code></pre> <p>Then everywhere you use <code>Pi</code> it is as if you typed <code>3.14</code>. Bacause <code>Pi</code> does not exist, as far as the compiler is concerned, you cannot even take an address of it to make a pointer to it.</p> <h3>Closest you can get to a dynamic <code>putch</code></h3> <p>Like the others have said, you can have some sort of case statement, conditional, or a global pointer, but the <code>putch</code> function itself has to be there in the same form.</p> <p>Global function pointer solution:</p> <pre><code> void (*myPutch)(char); putch(char ch) { myPutch(ch); } int main() { myPutch = putch_Type_A(); ... myPutch = putch_Type_B(); } </code></pre> <p>If/then/else solution has been provided in other answers</p> <p>goto solution: This would be an ugly (but fun!) hack, and only possible on von Neumann-type machines, but in these conditions you could have your <code>putch</code> look like this:</p> <pre><code> putch(char ch) { goto PutchTypeB PutchTypeA: // Code goes here return; PutchTypeB: // Code goes here return; } </code></pre> <p>You would then overwrite the <code>goto</code> instruction with goto to some other memory address. You'd have to figure out the opcodes for doing this (from disassembly, probably), and this isn't possible on Harvard architecture machines, so it is out on AVR processors, but it would be fun, if cludgey.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload