summaryrefslogtreecommitdiff
path: root/gemfeed/2016-11-20-methods-in-c.html
blob: fcdd5f0ace2216027f95c1e780cc0e3ad2978838 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Methods in C</title>
<link rel="shortcut icon" type="image/gif" href="/favicon.ico" />
<style type="text/css">
body {
  margin: auto;
  padding-left: 10px;
  padding-right: 10px;
  max-width: 900px;
  font-family: sans-serif;
  font-size: 18px;
  background-color: #222;
  color: #ffffef;
}

a {
  color: #0ca;
  text-decoration: none;
}

a:hover {
  color: #c0f;
  text-decoration: none;
}

img {
  max-width: 600px;
  max-height: 400px;
  display: block;
  margin: auto;
}

pre {
  display: block;
  background-color: #111;
  color: #fff;
  padding: 5px;
  overflow-x: auto;
}

a.textlink:before {
  content: " ⇒ ";
  padding-left: 2px;
}
</style>
</head>
<body>
<h1>Methods in C</h1>
<p class="quote"><i>Written by Paul Buetow 2016-11-20</i></p>
<p>You can do some sort of object-oriented programming in the C Programming Language. However, that is very limited. But also very easy and straightforward to use.</p>
<h2>Example</h2>
<p>Let's have a look at the following sample program. All you have to do is to add a function pointer such as "calculate" to the definition of struct "something_s". Later, during the struct initialization, assign a function address to that function pointer:</p>
<pre>
#include &lt;stdio.h&gt;

typedef struct {
    double (*calculate)(const double, const double);
    char *name;
} something_s;

double multiplication(const double a, const double b) {
    return a * b;
}

double division(const double a, const double b) {
    return a / b;
}

int main(void) {
    something_s mult = (something_s) {
        .calculate = multiplication,
        .name = "Multiplication"
    };

    something_s div = (something_s) {
        .calculate = division,
        .name = "Division"
    };

    const double a = 3, b = 2;

    printf("%s(%f, %f) =&gt; %f\n", mult.name, a, b, mult.calculate(a,b));
    printf("%s(%f, %f) =&gt; %f\n", div.name, a, b, div.calculate(a,b));
}
</pre>
<p>As you can see, you can call the function (pointed by the function pointer) the same way as in C++ or Java via:</p>
<pre>
printf("%s(%f, %f) =&gt; %f\n", mult.name, a, b, mult.calculate(a,b));
printf("%s(%f, %f) =&gt; %f\n", div.name, a, b, div.calculate(a,b));
</pre>
<p>However, that's just syntactic sugar for:</p>
<pre>
printf("%s(%f, %f) =&gt; %f\n", mult.name, a, b, (*mult.calculate)(a,b));
printf("%s(%f, %f) =&gt; %f\n", div.name, a, b, (*div.calculate)(a,b));
</pre>
<p>Output:</p>
<pre>
pbuetow ~/git/blog/source [38268]% gcc methods-in-c.c -o methods-in-c
pbuetow ~/git/blog/source [38269]% ./methods-in-c
Multiplication(3.000000, 2.000000) =&gt; 6.000000
Division(3.000000, 2.000000) =&gt; 1.500000
</pre>
<p>Not complicated at all, but nice to know and helps to make the code easier to read!</p>
<h2>The flaw</h2>
<p>However, that's not really how it works in object-oriented languages such as Java and C++. The method call in this example is not a method call as "mult" and "div" in this example are not "message receivers". I mean that the functions can not access the state of the "mult" and "div" struct objects. In C, you would need to do something like this instead if you wanted to access the state of "mult" from within the calculate function, you would have to pass it as an argument:</p>
<pre>
mult.calculate(mult,a,b));
</pre>
<p>How to overcome this? You need to take it further.</p>
<h2>Taking it further</h2>
<p>If you want to take it further, type "Object-Oriented Programming with ANSI-C" into your favourite internet search engine, you will find some crazy stuff. Some go as far as writing a C preprocessor in AWK, which takes some object-oriented pseudo-C and transforms it to plain C so that the C compiler can compile it to machine code. This is similar to how the C++ language had its origins.</p>
<p>E-Mail me your thoughts at comments@mx.buetow.org!</p>
<a class="textlink" href="../">Go back to the main site</a><br />
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Methods in C</title>
<link rel="shortcut icon" type="image/gif" href="/favicon.ico" />
<style type="text/css">
body {
  margin: auto;
  padding-left: 10px;
  padding-right: 10px;
  max-width: 900px;
  font-family: sans-serif;
  font-size: 18px;
  background-color: #222;
  color: #ffffef;
}

a {
  color: #0ca;
  text-decoration: none;
}

a:hover {
  color: #c0f;
  text-decoration: none;
}

img {
  max-width: 600px;
  max-height: 400px;
  display: block;
  margin: auto;
}

pre {
  display: block;
  background-color: #111;
  color: #fff;
  padding: 5px;
  overflow-x: auto;
}

a.textlink:before {
  content: " ⇒ ";
  padding-left: 2px;
}
</style>
</head>
<body>