diff options
author | Michiel Van Der Kolk <not.valid@email.address> | 2005-03-17 20:50:03 +0000 |
---|---|---|
committer | Michiel Van Der Kolk <not.valid@email.address> | 2005-03-17 20:50:03 +0000 |
commit | 27be5bc72855a0fbbdae230bc144624c9eb85f5e (patch) | |
tree | b553f1321df924c4b744ffcab48dce5f4f081f7d /apps/codecs/dumb/docs/fnptr.txt | |
parent | 7e7662bb716917ca431204f0113d400c1014f2e8 (diff) | |
download | rockbox-27be5bc72855a0fbbdae230bc144624c9eb85f5e.tar.gz rockbox-27be5bc72855a0fbbdae230bc144624c9eb85f5e.zip |
Initial check in dumb 0.9.2 - has a few usages of floating point that should
be rewritten to fixed point. seems to compile cleanly for iriver.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6197 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/dumb/docs/fnptr.txt')
-rw-r--r-- | apps/codecs/dumb/docs/fnptr.txt | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/apps/codecs/dumb/docs/fnptr.txt b/apps/codecs/dumb/docs/fnptr.txt new file mode 100644 index 0000000000..a5fb216822 --- /dev/null +++ b/apps/codecs/dumb/docs/fnptr.txt | |||
@@ -0,0 +1,113 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * fnptr.txt - Function pointer explanation. / / \ \ | ||
12 | * | < / \_ | ||
13 | * | \/ /\ / | ||
14 | * \_ / > / | ||
15 | * | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | |||
21 | C allows you to create and use function pointers. A function pointer is a | ||
22 | variable that points to a function, and you can use it to call that function. | ||
23 | Why is this useful? | ||
24 | |||
25 | Function pointers can be passed as parameters. As an example, here's a | ||
26 | function from Allegro: | ||
27 | |||
28 | void create_light_table(COLOR_MAP *table, const PALETTE pal, int r, g, b, | ||
29 | void (*callback)(int pos)); | ||
30 | |||
31 | Don't worry about the syntax just yet, but the last parameter, 'callback', is | ||
32 | a pointer to a function that takes an int parameter. create_light_table() can | ||
33 | take some time to complete its work, and you may want to display a progress | ||
34 | indicator. So you write a function to draw the progress indicator, and then, | ||
35 | for 'callback', you specify a pointer to your function. This will enable | ||
36 | create_light_table() to call your function at intervals during its | ||
37 | processing. (If you don't want to use the callback, you can pass NULL, but | ||
38 | this only works because create_light_table() checks actively for NULL. You | ||
39 | can't always specify NULL when you want nothing to happen.) | ||
40 | |||
41 | There are many other uses. In addition to using function pointers as | ||
42 | parameters, Allegro has some global function pointers you can set to point to | ||
43 | your functions. Function pointers can also be used in structs, and this is | ||
44 | where DUMB makes the most use of them. | ||
45 | |||
46 | So how are they used? | ||
47 | |||
48 | void bar(void) { ... } /* Here's a function */ | ||
49 | void (*foo)(void) = &bar; /* Take a pointer */ | ||
50 | (*foo)(); /* Call the function */ | ||
51 | |||
52 | char *baz(float a) { ... } /* Here's another function */ | ||
53 | char *(*foobarbaz)(float a) = &baz; /* Take a pointer */ | ||
54 | char *rv = (*foobarbaz)(0.1); /* Call the function */ | ||
55 | |||
56 | In both these cases, note how the statement for calling the pointed-to | ||
57 | function (third line) resembles the definition of the function pointer | ||
58 | (second line). This is true of any variable in C, and can lead to some truly | ||
59 | obfuscated definitions if you are that way inclined. Such definitions can be | ||
60 | clarified with typedefs, but before you use those, it is important you | ||
61 | understand how the above statements work. I speak from experience: function | ||
62 | pointer notation looks random and scary, until you understand why it's the | ||
63 | way it is; then it makes perfect sense. | ||
64 | |||
65 | (It is actually permissible to omit the & when taking a pointer and to write | ||
66 | e.g. foobarbaz(0.1) instead of (*foobarbaz)(0.1). However, I recommend not | ||
67 | doing this, since the syntax for using the pointer no longer resembles the | ||
68 | definition. Writing e.g. (*foobarbaz)(0.1) also makes a clear distinction | ||
69 | between function pointer calls and ordinary function calls, which makes code | ||
70 | more readable.) | ||
71 | |||
72 | Note that function pointers have the return value and parameter list | ||
73 | specified. A function pointer can only point to a function with a matching | ||
74 | return value and matching parameters. (You can break this rule by casting the | ||
75 | pointer explicitly, but there is no situation where doing so is portable to | ||
76 | all computers, and I strongly advise against it unless you're writing system | ||
77 | code. If you're not sure whether you're writing system code or not, then | ||
78 | you're not.) | ||
79 | |||
80 | The parameter names need not match (although the types must). If you wish to | ||
81 | rename a parameter in your function, you do not have to change the function | ||
82 | pointer accordingly. In fact, when you define a function pointer, you don't | ||
83 | even have to specify the names of parameters if you don't want to. I normally | ||
84 | do so for clarity. | ||
85 | |||
86 | It is possible to typedef a function pointer. In order to typedef a function | ||
87 | pointer, you start by declaring the pointer as a variable: | ||
88 | |||
89 | void (*myfunc)(void); | ||
90 | |||
91 | Then you write 'typedef' before it and replace the variable name, which is | ||
92 | myfunc, with the type name (this rule can be applied to any variable when you | ||
93 | want to use typedef): | ||
94 | |||
95 | typedef void (*MYTYPE)(void); | ||
96 | |||
97 | Now 'MYTYPE' represents a pointer to a function with no parameters and no | ||
98 | return value. The following two lines are completely equivalent: | ||
99 | |||
100 | MYTYPE myfunc; | ||
101 | void (*myfunc)(void); | ||
102 | |||
103 | Note that we use MYTYPE without an asterisk (*), since it is already a | ||
104 | pointer. | ||
105 | |||
106 | That's it. If you feel anything should be explained better here, or if you | ||
107 | feel something should be added, please don't hesitate to let me know! | ||
108 | |||
109 | |||
110 | Ben Davis | ||
111 | entheh@users.sf.net | ||
112 | IRC EFnet #dumb | ||
113 | See readme.txt for details on using IRC. | ||