Fun with C

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#16 Post by 01micko »

technosaurus wrote:What, no xcb + cairo-xcb port?
Rome wasn't built in a day :P
technosaurus wrote:j/k I know how difficult it is to find good xcb examples
This one looks useful as a start.
technosaurus wrote:- though I did find enough to write a very basic xcbmessage program a while back (no fancy cairo based images though)
I remember that! I had a bit of a look at xcb but went xlib because it fell into place ( = more docs and examples, which I referenced in the github readme). The program does what I want and looks ok, contrary to vovchik's "so goddamn ugly" comment. Of course the glam is all cairo.

Q> in your opinion, briefly, what are the advantages of xcb over xlib?
Puppy Linux Blog - contact me for access

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#17 Post by technosaurus »

01micko wrote:Q> in your opinion, briefly, what are the advantages of xcb over xlib?
xlib is ... xlib. xcb is smaller, faster and asynchronous You could have one thread sending requests, one handling responses, another handling errors and another (or a few) handling their callbacks while other threads handle program stuff. With xlib you send a request, wait for a response, handle, repeat. With glibc threads are actually pretty heavy (8MB+ or so each), but musl-libc has really lightweight threads (in the 10s of kb range). Now that quad-core processors with multiple execution units are a virtual standard even in mobile space, xcb _could_ really make a difference especially with openMP and other technologies that make it easier for us to take advantage. A few of us have been using musl pretty extensively and the rough edges are getting much smoother but we haven't really tested the threads much.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#18 Post by 01micko »

Interesting.

For my little venture, a very simple splash, xlib seems to suffice.

But..
technosaurus wrote:xcb is smaller, faster and asynchronous You could have one thread sending requests, one handling responses, another handling errors and another (or a few) handling their callbacks while other threads handle program stuff.
Remember when you had ideas to make icons for a JWM only desktop? What about xcb and cairo for that? Sure, a bit of a project. I don't think musl would support the cairo part though, not without extensive (probably way too much work) patching.
Puppy Linux Blog - contact me for access

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#19 Post by technosaurus »

see goingnuts' patches to idesk, they turned out pretty well.
It would be a shame to use an external program though, jwm already has everything in place to create them... I have even simulated icons using a solid color background and matching no-border trays for each icon (vertically oriented, fixed position with a icon+tooltip on top and optionally text on bottom) We only need a way to set individual tray background colors (probably as a property) and have the color be none (copy from parent)...not opacity as it is, that affects everything on the tray as well. If that happens I'll update my jwm tools to a 1.0 version.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
matiasbatero
Posts: 60
Joined: Fri 12 Oct 2012, 01:27
Location: Mar del Plata, Argentina

#20 Post by matiasbatero »

I'm new in programming. I'm started with C a week ago.

The code, compiles and runs OK.
But it is only a functional structure.

structs, pointers, unions etc.. in order to provide a:
"Readable post-code".
Attachments
str.c.tar
(5 KiB) Downloaded 243 times

jamesbond
Posts: 3433
Joined: Mon 26 Feb 2007, 05:02
Location: The Blue Marble

#21 Post by jamesbond »

My entry: Xannotate, a desktop annotation tool.

EDIT: add screenshot.

EDIT: Version 2014-07-27 now supports three pens, eraser, and support for alpha transparency (faster!) if you run a compositing manager (xcompmgr, compton, or kwin). Still works even if you don't have them.

Draw with left-button, erase with right-button. Shift-left-click changes pens. 'Pause' to enter/leave drawing mode, Shift-Pause to show/hide drawing, Ctrl-Pause to clear drawing and start over, Alt-Shift-Pause to capture a screenshot (in PNG format, with or without your drawing in it). Ctrl-Shift-Pause to exit.

And you can change "Pause" to something else.

Depends only on Xlib (libX11, libXext, libXrender) and pnglite which is included.
Attachments
xannotate00000.png
The annotation was done directly on screen, not in mtpaint
(43.07 KiB) Downloaded 689 times
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]

User avatar
Ted Dog
Posts: 3965
Joined: Wed 14 Sep 2005, 02:35
Location: Heart of Texas

#22 Post by Ted Dog »

JB how are you capturing keypresses would same be used for onscreen keyboard under fatdog64 and ARM? :D
I keep bringing this up because it has halted the project at a year now. I am having the yearly visit with the Dr. next week. She moved on and had most of our ideas done in window tablets since then. I posted a link to the news story ( That should have been a show with Fatdog !!) :wink:

User avatar
8-bit
Posts: 3406
Joined: Wed 04 Apr 2007, 03:37
Location: Oregon

#23 Post by 8-bit »

In writing something in C, sometimes one gets carried away in writing the code and fails to add sufficient comment sections to the code to explain what a section of the code is supposed to do.
And later, without comments in the code, one may go back to code he/she has written and be at a loss as to trying to make sense of it.
So with any C code, I recommend heavy commenting.
It only increases the source code file size and and does not increase the size of the compiled result.
Also, it helps others in understanding what the code does.

And keep in mind that C programmers may not have the level of experience you have. So cryptic comments will not help.

amigo
Posts: 2629
Joined: Mon 02 Apr 2007, 06:52

#24 Post by amigo »

I think programmers should spend their first five years only learning to write good comments... LOL

User avatar
Ted Dog
Posts: 3965
Joined: Wed 14 Sep 2005, 02:35
Location: Heart of Texas

#25 Post by Ted Dog »

8-bit wrote:In writing something in C, sometimes one gets carried away in writing the code and fails to add sufficient comment sections to the code to explain what a section of the code is supposed to do.
And later, without comments in the code, one may go back to code he/she has written and be at a loss as to trying to make sense of it.
So with any C code, I recommend heavy commenting.
It only increases the source code file size and and does not increase the size of the compiled result.
Also, it helps others in understanding what the code does.

And keep in mind that C programmers may not have the level of experience you have. So cryptic comments will not help.
I disagree. heavily commented code should be avoided to much cludder. Take a look at BKs scripts. Impossible to follow due to curtains of comments. On the other hand look and Kirks and JBs just enough at the key points of flow to speed understanding.
I followed a winner of the C http://www0.us.ioccc.org/
http://blog.aerojockey.com/post/iocccsim

in a job and ahhhhhh the horror. I took a c test that used the winners of that contest to get a job. I SO RAILED AGAINST that as a testing criteria I even correctly pointed out Carl had gave the interview the idea to use this as a C skill test, AND I WOULD NEVER SUBJECT ANYONE TO SUCH A NIGHTMARE, I do not justify my job security to code obfuscation. Got the job offer but refused ( second time working after Carl I learned my lession )

jamesbond
Posts: 3433
Joined: Mon 26 Feb 2007, 05:02
Location: The Blue Marble

#26 Post by jamesbond »

Ted Dog wrote:JB how are you capturing keypresses would same be used for onscreen keyboard under fatdog64 and ARM? :D
I keep bringing this up because it has halted the project at a year now. I am having the yearly visit with the Dr. next week. She moved on and had most of our ideas done in window tablets since then. I posted a link to the news story ( That should have been a show with Fatdog !!) :wink:
xvkbd should have worked. I remember I tested it and it did. I'm not too confident of matchbox_keyboard. Anyway, the way I capture the keyboard is XGrabKey - every X-based "hotkey" manager would do it that way, nothing special.

I have another entry for this: Xscreenshot, a simple program to take screenshot of selected area of the desktop. Its specialty: you can use it to quickly take successive screenshots. Especially useful when taking screenshot for documentation. Saves to PNG file. Depends only on Xlib.

xannotate is 22K, xscreenshot is 17K. This is on x86_64; I'm sure it is smaller on x86.

Enjoy.

From the readme:
README wrote:xscreenshot is a simple program to take screenshot of your desktop.

You can run it to take a single screenshot, or run it in multiple-shots mode.

The single-shot mode is meant to be used with other hotkey programs
(such as xbindkeys). In this mode, once you have taken your screenshot
it will exit. This is the default mode.

In multiple-shots mode, xscreenshot will run until you tell it to exit.
You can toggle between normal mode, or screenshot taking mode.
In normal mode, the mouse can be used as normal (hence the name).
In screenshot mode, you can take multiple screenshots, one after another.

The screenshot is saved as PNG file.

Mouse buttons
-------------
Left-click: press to start selection, move to choose, release to take a shot.
Right-click:
- if pressed during active selection (that is, when left-button is pressed too):
cancel selection, and you can start over.
- if pressed when there is no active selection:
- in single-shot mode, xscreenshot will exit
- in multiple-shot mode: no effect

Keys usage
----------
Hotkey - toggle screenshot/normal mode
Ctrl-Shift-hotkey - terminate xscreenshot
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#27 Post by 01micko »

More xlib/cairo fun ... I really should learn xcb next as xlib can suck :o

pmck

Compiled on 64 it's 20k stripped. Slightly less on x86.
readme wrote:pmck
====

a poor man's clock

This is a simple analog clock based on xlib and cairo.

This is not meant for production systems as it has bugs and was written just as
a proof of concept.

Build
-----
Just run 'make' and install the pmck the binary in your path. Optionally,
install the pmckrc file to $HOME/.config/ and edit to your preferences.

Usage
-----
Just run 'pmck' from the command line, it needs no options. It will read an rc file
in $HOME/.config/pmckrc to set different features. There is an example rc file
provided. This should be self explanatory. You can set the size, background
and foreground colours and the style, 2 to choose from. You can autostart it if
you wish. See your distro's documentation for this feature.

On some window managers the root window is not the desktop window. In the case
of ROX-Filer pinboard this is easily overcome by finding the child window which
is "ROX-Pinboard", which in most cases is the very first child. However, in the
case of XFCE I had trouble coding the correct window so added 1 single option to the
command line; the desktop window ID which can be found by running "xwininfo" and
clicking on a blank part of the desktop. The string will be a hex value something
like "0xae44010". Just type (or script) "pmck $hex_value_here". This should work
with any other WM/DE also as it overrides the internal algorithm.

Bugs
----
- must quit with CTRL-C or kill, there is code block supposed to quit with 'q'.. :(
- redraws forever, so may use too much CPU and eventually memory
- may run 1 or 2 seconds behind system time.
- need a click on desktop to display (rox bug - FIXED)
- some window managers may need the the window on top for the clock to display
- can flicker at times of heavy load or on slow machines
- a compositor such as xcompmgr is needed so artefacts do not display under clockface
- at larger sizes the second hand may flicker or disappear
Free virtual beer/coffee/other beverage for the one who solves the quit bug!
Puppy Linux Blog - contact me for access

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#28 Post by technosaurus »

maybe try

Code: Select all

	while (1) {
		XNextEvent(dpy, &e);
		if(e.type == Expose && e.xexpose.count < 1) {
			//while (1) {
				paint(cs, width, height, style);
			//	usleep(500000);
			//}

		} 
		else if (e.type == KeyPress) {
			char buf[128] = {0};
			KeySym keysym;
			XLookupString(&e.xkey, buf, sizeof buf, &keysym, NULL);
			if (keysym == XK_q) {
				break;
			}
		}
		usleep(500000); //moved here for cpu usage
	}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#29 Post by 01micko »

Nope. Clock doesn't redraw and it doesn't quit. Sorry, no chocolates.
Puppy Linux Blog - contact me for access

jamesbond
Posts: 3433
Joined: Mon 26 Feb 2007, 05:02
Location: The Blue Marble

#30 Post by jamesbond »

Make sure you prepare plenty of beers and chocolates :lol: Better make it real not virtual :lol: :lol:

change

Code: Select all

XSelectInput(dpy, win, ExposureMask|KeyPressMask);
to

Code: Select all

XSelectInput(dpy, win, ExposureMask|KeyPressMask|ButtonPressMask);
then change your loop to this one.

Code: Select all

	while (1) {
		while (XPending (dpy))
		{
			XNextEvent(dpy, &e);
			if (e.type == KeyPress) {
				char buf[128] = {0};
				KeySym keysym;
				XLookupString(&e.xkey, buf, sizeof(buf), &keysym, NULL);
				if (keysym == XK_q) {
					goto finish;
				}
			} else if (e.type == ButtonPress) {
				XSetInputFocus (dpy, win, RevertToNone, CurrentTime);
			}
		}
		paint(cs, width, height, style);
		usleep(500000);
	}
finish:
	cairo_surface_destroy(cs);
	XCloseDisplay(dpy);
To quit, click the clock, then press q.
On some window managers the root window is not the desktop window. In the case
of ROX-Filer pinboard this is easily overcome by finding the child window which
is "ROX-Pinboard", which in most cases is the very first child.
Doesn't work for me. I only run openbox + rox; and I have to resort to using xwininfo trick.
- a compositor such as xcompmgr is needed so artefacts do not display under clockface
Not enough. Do this: run pmck; cover it with something, show it again (and see the garbage), *then* run xcompmgr. xcompmgr will not remove that garbage (in fact it will keep it). Learn to use XShapeCombineMask instead, and you will not depend on xcompmgr at all.
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]

User avatar
01micko
Posts: 8741
Joined: Sat 11 Oct 2008, 13:39
Location: qld
Contact:

#31 Post by 01micko »

Almost :) ...Virtual only.

The problem is the logic. The clock draw needs it's own 'true' loop for some reason.. but of course that never ends so the next part of the program can't take place. So, I added the XPending() (EDIT: as you did but I shifted the paint() call to before the XPending())call to the true loop, reduced the sleep a bit and it works, but it tends to flicker a bit more. It's taking too long to draw. The clock face is quite complex, figuring out 56 different angles to draw at, plus font characters then the actual hand drawing operation. This (I think) can be sped up if I put the actual face on another surface, however, once the hands are drawn that surface needs to be refreshed. I'll think about that, (as I have done).

Code: Select all

while (1) { 
		paint(cs, width, height, style); 
		while (XPending (dpy)) { 
			XNextEvent(dpy, &e); 
			if (e.type == KeyPress) { 
				char buf[128] = {0}; 
				KeySym keysym; 
				XLookupString(&e.xkey, buf, sizeof(buf), &keysym, NULL); 
				if (keysym == XK_q) { 
				goto finish; 
				} 
			} else if (e.type == ButtonPress) { 
				XSetInputFocus (dpy, win, RevertToNone, CurrentTime); 
			} 
		}
		usleep(200000); /*reduced as Xpending() takes time */
	} 
finish: 
	cairo_surface_destroy(cs); 
	XCloseDisplay(dpy);  
As for the clock error for fatdog rox, maybe the desktop isn't the first child window? I guess I could test for that, one day :) .

I'll also look into XShapeCombineMask().

Image
Last edited by 01micko on Wed 30 Jul 2014, 02:07, edited 2 times in total.
Puppy Linux Blog - contact me for access

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#32 Post by technosaurus »

here is the beginning of object oriented C tutorial using structs and function pointers:

Code: Select all

#include <stdio.h>
/* this is an example how to use structs and function pointers for an imaginary camera API
each camera type can supply its own functions, properties etc... so we need a way to map the functions to our API
*/

/* we have to forward declare the struct due to circular reference */
struct camera_t;


/* functions operate on a single camera struct, modify it directly and return success/failure as int */
typedef int (*Fi)(camera_t *);

/* We'll use these to access functions, insert new ones before NUM_FUNCS */
enum{ NOOP, ZOOM_IN, ZOOM_OUT, ZOOM_STOP, INFRA_ON, INFRA_OFF, NUM_FUNCS};

typedef struct camera_t{
	unsigned properties;
	unsigned action;
	FILE *readbuf; /* using FILE* vs fd for portability ...win32 etc... */
	FILE *writebuf;
	Fi funcs[NUM_FUNCS]; /* note NUM_FUNCS as in previous enum */
}camera_t;

enum{
	zoomCapable = 1,
	zoomingIn = 2,
	zoomingOut = 4,
	infraredCapable = 8,
	infraredOn = 16,
	//.... =32, ...=64 etc...
};//flags to be set in properties

/* provide a noop action for first function and unsupported functions*/
int noop(camera_t cam){return 0;}
//these would be in the camera's header/object included as reference
int startZoomIn(camera_t *cam);//ZOOM_IN
int startZoomOut(camera_t *cam);//ZOOM_OUT
int stopZoom(camera_t *cam);//ZOOM_STOP
int infraOn(camera_t *cam);//INFRA_ON
int infraOff(camera_t *cam);//INFRA_OFF

/* using a macro to initialize a struct directly provides more compact code
   than initializing each member separately in a function and returning it.
*/
#define initCam(name, prop,action,rbuf,wbuf,zin,zout,zstop,ion,ioff) \
    camera_t name = {prop,action,rbuf,wbuf,{noop,zin,zout,zstop,ion,ioff}}

//assign camera's corresponding functions in same order as enum above 
initCam(mycam,zoomCapable|infraredCapable, 0, stdin, stdout, startZoomIn,
         startZoomOut,stopZoom,infraOn,infraOff);

//usage
mycam.funcs[INFRA_ON](&mycam);
/* notice the &, that is because the functions take a pointer to a camera_t struct;
the & give the address of mycam, which is the same as if we set up a pointer to it.
This allows all of our functions to operate on a single instance of camera_t without copying it into and out of functions.
This reduces code size and complexity, while allowing us to use an int return value to indicate error/success
*/

/* more complex usage */
int run(camera_t *cam){
  unsigned action = cam->action; //use a local copy so we can reset .action
  cam->action=0; //reset the action
/* note the  '->' and no '&' now vs. '.' with '&cam'; we are using a pointer to camera_t */
  if (action< NUM_FUNCS) return cam->funcs[action](cam);
  else return -1;
}
while(1){
  if (mycam.action && run(&mycam) == -1)
    printf("error"); /*could add: %d\n", errno); or similar here */
  sleep(1); /* only handle events once per second to reduce cpu usage*/
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

jamesbond
Posts: 3433
Joined: Mon 26 Feb 2007, 05:02
Location: The Blue Marble

#33 Post by jamesbond »

01micko wrote:but it tends to flicker a bit more.
Try this to reduce the flicker:

instead of

Code: Select all

cs = cairo_xlib_surface_create(dpy, win, 
				DefaultVisual(dpy, scr), width, height);
use

Code: Select all

	Pixmap pixmap = XCreatePixmap (dpy, win, width, height, mydepth);
	XFillRectangle (dpy, pixmap, DefaultGC(dpy, scr), 0,0, width, height);
	cs = cairo_xlib_surface_create(dpy, pixmap, 
				DefaultVisual(dpy, scr), width, height);
And after

Code: Select all

paint(cs, width, height, style);
you add

Code: Select all

XCopyArea (dpy, pixmap, win, DefaultGC (dpy, scr), 0,0, width, height, 0,0);
As a downside you'll get black corners around the the clock, but that's one more reason why you should learn XShapeCombineMask :)


EDIT: you can also do this in the "pure cairo" way by using a second cairo surface, like this:

Code: Select all

	cs = cairo_xlib_surface_create(dpy, win, 
				DefaultVisual(dpy, scr), width, height);
	cairo_surface_t *csbuf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);				
	cairo_t *cspaint = cairo_create (cs);
	cairo_set_source_surface (cspaint, csbuf, 0, 0);
and

Code: Select all

		paint(csbuf, width, height, style);
		cairo_paint (cspaint);
Of course, don't mix the Pixmap method and the pure cairo method - use either one :)
Fatdog64 forum links: [url=http://murga-linux.com/puppy/viewtopic.php?t=117546]Latest version[/url] | [url=https://cutt.ly/ke8sn5H]Contributed packages[/url] | [url=https://cutt.ly/se8scrb]ISO builder[/url]

mcewanw
Posts: 3169
Joined: Thu 16 Aug 2007, 10:48
Contact:

#34 Post by mcewanw »

darkcity wrote: For anyone wanting to learn this language I'd recommend it.
http://c.learncodethehardway.org/book/
hmmm... It's been about 6 years since I last programmed in C, but I thought I'd take a look at the recommended book as an alternative to my trusty old Kernighan and Dennis Ritchie (K&R) C book (which the author of the above book seems to somewhat despise...). All I can say is that this new book's teaching approach is to start reasonably slow and then, suddenly, jump in the deep end! I imagine 'some' newcomers to C will have a brain explosion (or implosion) when they are suddenly confronted with Ch17 and 18 (they probably won't find ch 15 or 16 particulary easy either, but the killer blow will be ch 17 I think!).

Unfortunately (as far as this recommended book is concerned), I love the K&R style of C programming (which is probably me showing my age), preferring pointer arithmetic to array indexing always, so some of the code style in the book is as painful to me as K&R style is to the author. I haven't read the whole thing yet, so can't comment on his claims that K&R includes a lot of bad code - I can say, however, that K&R includes lots of nice diagrams, which, as far as I'm concerned, nicely explain the subtle differences in how array indexing works compared to using pointers. Perhaps compilers have ironed out the differences nowadays, but still, I like a diagram or two in order to illustrate how C views memory. A picture is indeed worth a thousand words.

I'm not saying this is a bad book, however; for quick learners, who don't mind deep water, it may be very good, but for many newbies I think it could make them feel that C is impossibly hard to learn, which it isn't. Best for such learners, that they stick with the simpler basics first and then try to get their heads round pointers (which aren't so difficult actually, and little diagramatic pictures of 'what's pointing to what' really help), without jumping off the deep end until they are sure they are still afloat...

From memory, what I liked most about the K&R C book, is that it really reinforces how close to UNIX, C is, so after working through the book you really also begin to understand UNIX/Linux at a deeper system level, which leaves you understanding better the relationship between processes and their children and so on. The drawback of K&R may be that it is somewhat dry and technical in style - it hasn't been written to keep the reader amused... and it is now an ancient book of course.

William

EDIT: Actually, the example code in ch 18 is rather nice. The author is clearly very used to object oriented programming and likes C to be molded to mimic that. I like the way he uses compare_cb, via pointers to function to override the actual operation of the function, which is like a form of polymorphism (the actual function used changes depending on whether, sorted-order, reverse order, or strange-order, is passed to the test-sorting routine).
github mcewanw

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#35 Post by technosaurus »

mcewanw wrote:... preferring pointer arithmetic to array indexing always, so some of the code style in the book is as painful to me as K&R style is to the author ...what I liked most about the K&R C book, is that it really reinforces how close to UNIX, C is, so after working through the book you really also begin to understand UNIX/Linux at a deeper system level, which leaves you understanding better the relationship between processes and their children and so on. The drawback of K&R may be that it is somewhat dry and technical in style - it hasn't been written to keep the reader amused... and it is now an ancient book of course.

William

EDIT: Actually, the example code in ch 18 is rather nice. The author is clearly very used to object oriented programming and likes C to be molded to mimic that. I like the way he uses compare_cb, via pointers to function to override the actual operation of the function, which is like a form of polymorphism (the actual function used changes depending on whether, sorted-order, reverse order, or strange-order, is passed to the test-sorting routine).
K&R was written before many of the C standards were implemented, so it was common to use things like:

Code: Select all

void* (*f)()=dlsym(handle, "my_function");
which by C standards breaks about 10 different rules at once but reduces code complexity immensely because it can handle any number of arguments and any return type where the return size is <= the size of void* and get automatically casted. By the standard, one would have to do all kinds of ridiculousness to handle every combination _and_ create a mechanism to know which one to use (libffi does a lot of these or my K&R style example here)
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

Post Reply