From 37485bba8e127be8bb3bd6e42093c0275ecccefd Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 29 Jan 2022 22:15:01 +0000 Subject: Publishing new version --- gemfeed/2016-11-20-methods-in-c.gmi | 86 ----------------- ...-20-object-oriented-programming-with-ansi-c.gmi | 103 +++++++++++++++++++++ gemfeed/atom.xml | 46 +++++---- gemfeed/index.gmi | 2 +- index.gmi | 2 +- 5 files changed, 134 insertions(+), 105 deletions(-) delete mode 100644 gemfeed/2016-11-20-methods-in-c.gmi create mode 100644 gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi diff --git a/gemfeed/2016-11-20-methods-in-c.gmi b/gemfeed/2016-11-20-methods-in-c.gmi deleted file mode 100644 index ea2e585d..00000000 --- a/gemfeed/2016-11-20-methods-in-c.gmi +++ /dev/null @@ -1,86 +0,0 @@ -# Methods in C - -> Published by Paul at 2016-11-20 - -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. - -## Example - -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: - -``` -#include - -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) => %f\n", mult.name, a, b, mult.calculate(a,b)); - printf("%s(%f, %f) => %f\n", div.name, a, b, div.calculate(a,b)); -} -``` - -As you can see, you can call the function (pointed by the function pointer) the same way as in C++ or Java via: - -``` -printf("%s(%f, %f) => %f\n", mult.name, a, b, mult.calculate(a,b)); -printf("%s(%f, %f) => %f\n", div.name, a, b, div.calculate(a,b)); -``` - -However, that's just syntactic sugar for: - -``` -printf("%s(%f, %f) => %f\n", mult.name, a, b, (*mult.calculate)(a,b)); -printf("%s(%f, %f) => %f\n", div.name, a, b, (*div.calculate)(a,b)); -``` - -Output: - -``` -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) => 6.000000 -Division(3.000000, 2.000000) => 1.500000 -``` - -Not complicated at all, but nice to know and helps to make the code easier to read! - -## The flaw - -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: - -``` -mult.calculate(mult,a,b)); -``` - -How to overcome this? You need to take it further. - -## Taking it further - -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. - -E-Mail me your comments to paul at buetow dot org! - -=> ../ Go back to the main site diff --git a/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi b/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi new file mode 100644 index 00000000..4af65381 --- /dev/null +++ b/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi @@ -0,0 +1,103 @@ +# Object oriented programming with ANSI C + +``` + ___ ___ ____ ____ + / _ \ / _ \| _ \ / ___| +| | | | | | | |_) |____| | +| |_| | |_| | __/_____| |___ + \___/ \___/|_| \____| + +``` + +> Published by Paul at 2016-11-20, updated 2022-01-29 + +You can do a little of object-oriented programming in the C Programming Language. However, that is, in my humble opinion, limited. It's easier to use a different programming language than C for OOP. But still it's an interesting exercise to try using C for this. + +## Function pointers + +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: + +``` +#include + +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) => %f\n", mult.name, a, b, mult.calculate(a,b)); + printf("%s(%f, %f) => %f\n", div.name, a, b, div.calculate(a,b)); +} +``` + +As you can see, you can call the function (pointed by the function pointer) with the same syntax as in C++ or Java: + +``` +printf("%s(%f, %f) => %f\n", mult.name, a, b, mult.calculate(a,b)); +printf("%s(%f, %f) => %f\n", div.name, a, b, div.calculate(a,b)); +``` + +However, that's just syntactic sugar for: + +``` +printf("%s(%f, %f) => %f\n", mult.name, a, b, (*mult.calculate)(a,b)); +printf("%s(%f, %f) => %f\n", div.name, a, b, (*div.calculate)(a,b)); +``` + +Output: + +``` +pbuetow ~/git/blog/source [38268]% gcc oop-c-example.c -o oop-c-example +pbuetow ~/git/blog/source [38269]% ./oop-c-example +Multiplication(3.000000, 2.000000) => 6.000000 +Division(3.000000, 2.000000) => 1.500000 +``` + +Not complicated at all, but nice to know and helps to make the code easier to read! + +## That's not OOP, though + +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: + +``` +mult.calculate(mult,a,b)); +``` + +## Real object oriented proramming with C + +If you want to take it further, hit "Object-Oriented Programming with ANSI-C" into your favourite internet search engine or follow the link below. It goes 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. + +=> https://www.cs.rit.edu/~ats/books/ooc.pdf + +## OOP design patterns in the Linux Kernel + +Big C software projects, like Linux, also follow some OOP techniques: + +=> https://lwn.net/Articles/444910/ + +C is a very old programming lanuage with it's quirks. This might be one of the reasons why Linux will also let Rust code in. + +E-Mail me your comments to paul at buetow dot org! + +=> ../ Go back to the main site diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml index 2c7a597e..07e4b69b 100644 --- a/gemfeed/atom.xml +++ b/gemfeed/atom.xml @@ -1,6 +1,6 @@ - 2022-01-23T22:20:22+00:00 + 2022-01-29T22:10:52+00:00 foo.zone feed To be in the .zone! @@ -1986,21 +1986,29 @@ Total time: 1213.00s - Methods in C - - gemini://foo.zone/gemfeed/2016-11-20-methods-in-c.gmi - 2016-11-20T18:36:51+01:00 + Object oriented programming with ANSI C + + gemini://foo.zone/gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi + 2016-11-20T22:10:57+00:00 Paul Buetow comments@mx.buetow.org - You can do some sort of object oriented programming in the C Programming Language. However, that is very limited. But also very easy and straight forward to use.. .....to read on please visit my site. + You can do a little of object-oriented programming in the C Programming Language. However, that is, in my humble opinion, limited. It's easier to use a different programming language than C for OOP. But still it's an interesting exercise to try using C for this.. .....to read on please visit my site.
-

Methods in C

-

Published by Paul at 2016-11-20

-

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.

-

Example

+

Object oriented programming with ANSI C

+
+  ___   ___  ____        ____ 
+ / _ \ / _ \|  _ \      / ___|
+| | | | | | | |_) |____| |    
+| |_| | |_| |  __/_____| |___ 
+ \___/ \___/|_|         \____|
+                              
+
+

Published by Paul at 2016-11-20, updated 2022-01-29

+

You can do a little of object-oriented programming in the C Programming Language. However, that is, in my humble opinion, limited. It's easier to use a different programming language than C for OOP. But still it's an interesting exercise to try using C for this.

+

Function pointers

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:

 #include <stdio.h>
@@ -2035,7 +2043,7 @@ int main(void) {
     printf("%s(%f, %f) => %f\n", div.name, a, b, div.calculate(a,b));
 }
 
-

As you can see, you can call the function (pointed by the function pointer) the same way as in C++ or Java via:

+

As you can see, you can call the function (pointed by the function pointer) with the same syntax as in C++ or Java:

 printf("%s(%f, %f) => %f\n", mult.name, a, b, mult.calculate(a,b));
 printf("%s(%f, %f) => %f\n", div.name, a, b, div.calculate(a,b));
@@ -2047,20 +2055,24 @@ printf("%s(%f, %f) => %f\n", div.name, a, b, (*div.calculate)(a,b));
 

Output:

-pbuetow ~/git/blog/source [38268]% gcc methods-in-c.c -o methods-in-c
-pbuetow ~/git/blog/source [38269]% ./methods-in-c
+pbuetow ~/git/blog/source [38268]% gcc oop-c-example.c -o oop-c-example
+pbuetow ~/git/blog/source [38269]% ./oop-c-example
 Multiplication(3.000000, 2.000000) => 6.000000
 Division(3.000000, 2.000000) => 1.500000
 

Not complicated at all, but nice to know and helps to make the code easier to read!

-

The flaw

+

That's not OOP, though

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:

 mult.calculate(mult,a,b));
 
-

How to overcome this? You need to take it further.

-

Taking it further

-

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.

+

Real object oriented proramming with C

+

If you want to take it further, hit "Object-Oriented Programming with ANSI-C" into your favourite internet search engine or follow the link below. It goes 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.

+https://www.cs.rit.edu/~ats/books/ooc.pdf
+

OOP design patterns in the Linux Kernel

+

Big C software projects, like Linux, also follow some OOP techniques:

+https://lwn.net/Articles/444910/
+

C is a very old programming lanuage with it's quirks. This might be one of the reasons why Linux will also let Rust code in.

E-Mail me your comments to paul at buetow dot org!

diff --git a/gemfeed/index.gmi b/gemfeed/index.gmi index 07c7b64e..963a84ef 100644 --- a/gemfeed/index.gmi +++ b/gemfeed/index.gmi @@ -15,7 +15,7 @@ => ./2021-04-24-welcome-to-the-geminispace.gmi 2021-04-24 (0802 words) - Welcome to the Geminispace => ./2021-04-22-dtail-the-distributed-log-tail-program.gmi 2021-04-22 (2122 words) - DTail - The distributed log tail program => ./2018-06-01-realistic-load-testing-with-ioriot-for-linux.gmi 2018-06-01 (2176 words) - Realistic load testing with I/O Riot for Linux -=> ./2016-11-20-methods-in-c.gmi 2016-11-20 (0318 words) - Methods in C +=> ./2016-11-20-object-oriented-programming-with-ansi-c.gmi 2016-11-20 (0385 words) - Object oriented programming with ANSI C => ./2016-05-22-spinning-up-my-own-authoritative-dns-servers.gmi 2016-05-22 (0512 words) - Spinning up my own authoritative DNS servers => ./2016-04-16-offsite-backup-with-zfs-part2.gmi 2016-04-16 (0248 words) - Offsite backup with ZFS (Part 2) => ./2016-04-09-jails-and-zfs-on-freebsd-with-puppet.gmi 2016-04-09 (0425 words) - Jails and ZFS with Puppet on FreeBSD diff --git a/index.gmi b/index.gmi index 5e8bf1e5..3bbb4dd4 100644 --- a/index.gmi +++ b/index.gmi @@ -65,7 +65,7 @@ I have switched blog software multiple times. I might be backfilling some of the => ./gemfeed/2021-04-24-welcome-to-the-geminispace.gmi 2021-04-24 - Welcome to the Geminispace => ./gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.gmi 2021-04-22 - DTail - The distributed log tail program => ./gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.gmi 2018-06-01 - Realistic load testing with I/O Riot for Linux -=> ./gemfeed/2016-11-20-methods-in-c.gmi 2016-11-20 - Methods in C +=> ./gemfeed/2016-11-20-object-oriented-programming-with-ansi-c.gmi 2016-11-20 - Object oriented programming with ANSI C => ./gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.gmi 2016-05-22 - Spinning up my own authoritative DNS servers => ./gemfeed/2016-04-16-offsite-backup-with-zfs-part2.gmi 2016-04-16 - Offsite backup with ZFS (Part 2) => ./gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.gmi 2016-04-09 - Jails and ZFS with Puppet on FreeBSD -- cgit v1.2.3