Literature Recommendations for C

Hi there,
I just hit vacation time and wanted to spend some time going a bit more in depth at C and maybe get some other Languages started.
I’ve head a “basic C course” and want to look deeper into it and specifically into programming Microcontrollers (stm32 to be precise). I am currently coding mostly using Vim so I am also interested to learn Vim script. I also already got K&R C programming language so I am mostly looking for a new take on C specifically for MCUs.

1 Like

Got you fam

2 Likes

He already got it.

Not gonna lie, I only read his title from the aggregate page when I made my suggestion.

Expert C Programming: Deep C Secrets by Peter van der Linden has some pretty good chapters, although it isn’t aimed specifically at embedded systems.

Chapter 3 has some “barn burner” declarations, like:

char *(*c[10])(int ** p);

Chapters 4, 9, 10 are pretty exhaustive on the subtle differences on the way the memory model treats pointers, arrays, array parameters to functions and their respective declarations.

Thanks for the suggestion, but i think this one is a bit over my head. Maybe gonna give it a try anyways.

char *(*c[10])(int **p) is an array of function pointers.

$ cat > x.c <<EOF
#include <stdio.h>

char *f( int **p ) {
  static char ok[ 4 ] = "ok0";
  ok[ 2 ] += **p;
  return ok;
}

int
main( int argc, char *argv[] ) {
  int i = 8, *iptr = &i;
  char *(*c[10])(int **p);
  c[ 0 ] = f;
  printf( "f() = %s\n", c[ 0 ]( &iptr ) );
  return 0;
}
EOF
$ gcc x.c
$ a.out
f() = ok8

Extra credit. Which one of these programs prints “hello”?

  1. First entry
#include <stdio.h>
#include <string.h>

int
main( int argc, char *argv[] ) {
  char (*(*c)[10])[10];
  char (*x[10])[10];
  char y[10];
  strcpy( y, "hello" );
  x[0] = &y;
  c = &x;
  printf( "%s\n", c[0][0] );
  return 0;
}
  1. Second entry
#include <stdio.h>
#include <string.h>

int
main( int argc, char *argv[] ) {
  char **c[10][10];
  char *x[10][10];
  char y[10];
  strcpy( y, "hello" );
  x[0][0] = y;
  c[0][0] = x[0];
  printf( "%s\n", c[0][0] );
  return 0;
}

I think

char **c[10][10];

and

char *x[10][10];

are probably generally bugs, and are definitely bugs in your specific examples.

 char (*(*c)[10])[10];

means c is a pointer to a 10 element array of pointers to a 10 element array of chars. And

char (*x[10])[10];

means x is a 10 element array of pointers to a 10 element array of chars. And appear to be used correctly to ultimately print hello. 2 either prints uninitialized garbage or faults.

Best book for beginners IMO.

Cheers,
-C-

1 Like

Yep, number 1 is right. I don’t like the crazy pointer to array notation of the C typesystem. It’s very hard to parse. Add in the crazy template system of C++ and now you have a language only understood by aliens. They should change the naming system of C++ versions from C++18 to C++wtf.

In number 2, change this line and voila, hello appears:

  printf( "%s\n", *c[0][0] );