Author Topic: Good C programming books  (Read 1892 times)

0 Members and 1 Guest are viewing this topic.

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 1122
  • Country: nz
  • Currently at SiFive, previously Samsung R&D
Re: Good C programming books
« Reply #25 on: September 29, 2019, 06:57:49 pm »
I learned and used C before C++, but there wasn't a choice in my case. It was before C++ was created.

I also learned the VI editor before the computer mouse was a thing. It's still worth using as well, and the fact that you still don't have to have a mouse to use it is a good thing.

I learned C and vi together in 1982, on "Eunice" under VMS. The next year we had real Unix on a Zilog System 8000.

C was fine. A bit uglier than Pascal or Modula 2, but usable. I bought the first Zortech C++ compiler (for DOS) and ran it on a Mac under VirtualPC. Within a year Apple had C++ as part of MPW (Macintosh Programmer's Workshop) and I switched all my development from C and Pascal to C++.

I hated vi right from the start. So crude compared to EDT or EVE on the VAX. Still, that's what Unix systems had, so that's what I learned to use.

I don't think I had access to a proper emacs until 1996 or so when I started to use Linux and also acquired a cast-off SPARCStation ELC with Solaris. It was love at first keystrokes and I dropped vi like a hot potato. Ever since then I've used emacs as my primary editor no matter what OS I'm on: Linux, Mac, or Windows.
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 10034
  • Country: gb
    • Having fun doing more, with less
Re: Good C programming books
« Reply #26 on: September 29, 2019, 07:20:06 pm »
I learned and used C before C++, but there wasn't a choice in my case. It was before C++ was created.

I also learned the VI editor before the computer mouse was a thing. It's still worth using as well, and the fact that you still don't have to have a mouse to use it is a good thing.

I learned C and vi together in 1982, on "Eunice" under VMS. The next year we had real Unix on a Zilog System 8000.

So did I, except it was on that decent operating system from Microsoft: Xenix.

Fortunately it also had a rather tasteful editor from a young James Gosling (subsequently of Java fame), Unipress emacs.

Quote
I hated vi right from the start. So crude compared to EDT or EVE on the VAX. Still, that's what Unix systems had, so that's what I learned to use.

Ah yes, EDT. The trouble with that was that if you hit "delete word/character", it would delete one of two words/characters depending on what you had been doing some time in the past. If you last moved forwards(backwards) then it deleted the next word forward(backward).

Fortunately you could override that idiocy via macros.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 6534
  • Country: us
Re: Good C programming books
« Reply #27 on: October 04, 2019, 04:41:45 pm »
If you want to learn C, the original book
"The C programming language"
by Kernighan and Ritchie.

As others have pointed out, it will not directly work on Arduino. Some tailoring required.

Personally, I have not seen ANY Arduino example code that even bearly resembles C++
It all looks like some sort of C.

Everybody should have that book on their bookshelf, it's a classic!  The "ANSI Version" should be on the desk.
https://www.amazon.com/Programming-Language-ANSI-Version/dp/8131704947

When working with the Arduino, learning C is a secondary topic.  The more important part of the project will be interacting with the hardware.

Everything that can possibly be done with an Arduino has already been done and the project is out on the Internet, complete with code.  Pretty much everything can be built with copy-and-paste.

Still, the Arduino code is mostly C and is useful for a learning environment.  But, in the end, it's all about interacting with the hardware and library code abounds.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 1380
  • Country: us
Re: Good C programming books
« Reply #28 on: October 05, 2019, 12:06:54 am »
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 2859
  • Country: us
Re: Good C programming books
« Reply #29 on: October 05, 2019, 12:47:21 am »
I'll put in a word for "C Traps and Pitfalls", by Andrew Koenig. It doesn't pretend to be comprehensive, but it covers many of the most common mistakes that are easy to overlook, either by inexperienced programmers or due to shortcomings of the language and operating environments. It's pretty old, so some of the more recent issues around Undefined Behavior are not explored in as much detail as you can find today.
 

Offline jackthomson41

  • Regular Contributor
  • *
  • Posts: 53
  • Country: us
Re: Good C programming books
« Reply #30 on: October 10, 2019, 03:58:18 pm »
For learning Embedded, the best book is "PIC Microcontroller & Embedded Systems using Assembly & C Language" by Mazidi , there are also his books for Atmel & AVR.
 

Offline SimonR

  • Regular Contributor
  • *
  • Posts: 111
  • Country: gb
Re: Good C programming books
« Reply #31 on: October 21, 2019, 04:00:03 pm »

Code: [Select]
void loop() {
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue);
  delay(1);
}

What the heck do you call Serial.println(sensorValue)? That can only be C++ (or Java), not C.

You're wrong its completely legal C.

couldn't you store the pointer to a function in a structure?

You're right you can

Code: [Select]
struct {
    void(*println)(int);
} Serial = {printfunction};

void loop() {
  int sensorValue = analogRead(0xA0);
  Serial.println(sensorValue);
  delay(1);
}
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 2859
  • Country: us
Re: Good C programming books
« Reply #32 on: October 22, 2019, 10:26:16 pm »
So a function named println is only capable of taking ints? Something is very fishy here.

The reason that the code cannot be C is that it uses polymorphism (the printing function is either overloaded or uses template metaprogramming), not the presence of the direct selection operator.
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 1591
  • Country: us
Re: Good C programming books
« Reply #33 on: October 22, 2019, 11:40:52 pm »
So a function named println is only capable of taking ints? Something is very fishy here.

The reason that the code cannot be C is that it uses polymorphism (the printing function is either overloaded or uses template metaprogramming), not the presence of the direct selection operator.

Pretend he wrote "foo" instead of "println" then, and that foo is declared as "void foo(int);". Then you won't drag in unstated assumptions about unstated libraries that have nothing to do with the point being demonstrated.
« Last Edit: October 22, 2019, 11:42:32 pm by Nusa »
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 1122
  • Country: nz
  • Currently at SiFive, previously Samsung R&D
Re: Good C programming books
« Reply #34 on: October 23, 2019, 02:31:54 am »
So a function named println is only capable of taking ints? Something is very fishy here.

The reason that the code cannot be C is that it uses polymorphism (the printing function is either overloaded or uses template metaprogramming), not the presence of the direct selection operator.

Pretend he wrote "foo" instead of "println" then, and that foo is declared as "void foo(int);". Then you won't drag in unstated assumptions about unstated libraries that have nothing to do with the point being demonstrated.

Here is "ASCIITable", one of the demo programs included with the Arduino IDE (with absolute beginner comments stripped out for compactness):

Code: [Select]
void setup() {
  Serial.begin(9600);
  while (!Serial) {
  }
  Serial.println("ASCII Table ~ Character Map");
}

int thisByte = 33;

void loop() {
  Serial.write(thisByte);
  Serial.print(", dec: ");
  Serial.print(thisByte);
  Serial.print(", hex: ");
  Serial.print(thisByte, HEX);
  Serial.print(", oct: ");
  Serial.print(thisByte, OCT);
  Serial.print(", bin: ");
  Serial.println(thisByte, BIN);

  if (thisByte == '-') {
    while (true) {
      continue;
    }
  }
  thisByte++;
}

Please explain how this could be C, not C++.

The context was clearly "the Arduino language", so the Arduino library is hardly an "unstated assumption".
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 1591
  • Country: us
Re: Good C programming books
« Reply #35 on: October 23, 2019, 04:31:30 am »
Except that SimonR's point was that that syntax was possible in C. He'd have to have his own println() function, but it's POSSIBLE.

But, now that you've pointed out the context, yes, the Arduino implementation of Serial is certainly a C++ object. The source code is easily found if you really want to see the implementation. There's no mystery at all if one knows enough to read it.

When someone talks about the "Arduino Language", if you choose to call it that, it means they're using a C++ compiler with a library of documented functions, implemented both C and C++, built on top of the wiring framework (implemented in C, usually), which in turn is another library with a default main() that calls setup() and loop() and a collection of hardware interface functions.

All of which is completely optional. You'll notice in my examples above, I used a main(), and the only wiring functions I called were init() and delay(). I didn't feel the need to spend time implementing delay() myself for an example.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #36 on: October 24, 2019, 04:25:44 am »
Quote
Quote
Code: [Select]
  Serial.println(sensorValue);What the heck do you call Serial.println(sensorValue)? That can only be C++ (or Java), not C.
You're wrong its completely legal C.
As soon as you make it:
Code: [Select]
  Serial.println("Sensor Value is");
  Serial.println(sensorValue);
You need C++ (assuming that "sensorValue" isn't a char* pointer or literal string.)
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #37 on: October 24, 2019, 03:41:14 pm »
Yup. We already went through this with the real "Serial" declaration itself, which could not be C.

Of course, if you conveniently omit its declaration (or provide a different one), the rest of the code could look like C, but as westfw just noted, the fact that parameters of different and incompatibles types are passed to the println() function shows it can't be C.

Checkmate. :horse:

Edit: For the most up-to-date C programmers out there, this isn't entirely true. If you're using a C11-compliant compiler, you could have defined println() as a macro, using the new _Generic keyword, expanding to different versions of the println() function depending on the type of its parameters.
So...
Yes, it could be C11. How many of you know the C11 additions though? ::)
And then, the typical declaration of objects (using constructors), which are used ubiquitously in Arduino's libraries, would still not work.

In the end, are we going to endlessly arguing that Arduino could be C(11), whereas it's clearly built on C++?

« Last Edit: October 24, 2019, 03:51:30 pm by SiliconWizard »
 

Offline bsfeechannel

  • Frequent Contributor
  • **
  • Posts: 893
  • Country: 00
Re: Good C programming books
« Reply #38 on: October 24, 2019, 05:43:53 pm »
And then, the typical declaration of objects (using constructors), which are used ubiquitously in Arduino's libraries, would still not work.

You mean like that?
Code: [Select]
#include "Class.h"

int main()
{
Class obj = Class( 1 );
}

Code: [Select]
//Class.h
 #define Class( x ) { (x) }

typedef struct {
int somerandomvariable;
} Class;
« Last Edit: October 24, 2019, 05:57:56 pm by bsfeechannel »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #39 on: October 24, 2019, 07:26:20 pm »
Ahah, good one. It's relying on the fact that function-like macros are expanded only if invoked with the parentheses. Although it can find some practical uses, I would consider doing this really bad coding practice. But anyway, this wasn't the point I guess.

I see this has become a C++ look-alike contest. Or I dunno what.

Still, your example doesn't cover the much more usual way of using constructors implicitly, which can be seen in almost all Arduino code: (actually I hadn't seen the explicit way in like ages, except with the 'new' operator)
Code: [Select]
Class obj(1);
Seriously guys. Arduino is all built on C++. Deal with it and move on.
« Last Edit: October 24, 2019, 07:28:21 pm by SiliconWizard »
 

Offline dunkemhigh

  • Super Contributor
  • ***
  • Posts: 1459
Re: Good C programming books
« Reply #40 on: October 25, 2019, 02:47:28 pm »
Quote
the fact that parameters of different and incompatibles types are passed to the println() function shows it can't be C

Code: [Select]
#define cppclone(...)   cppfake(unused, __VA_ARGS__)
Quote
Checkmate.

Practically, but literally?
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #41 on: October 26, 2019, 12:38:00 am »
Quote
the fact that parameters of different and incompatibles types are passed to the println() function shows it can't be C

Code: [Select]
#define cppclone(...)   cppfake(unused, __VA_ARGS__)

Hehe. I see this has sparked some kind of contest. Looks a bit like an obfuscated C contest of some kind, but that's fun.
As I said in my "edit" section, there's actually a standard way of doing this properly in C11 with the _Generic keyword. For people interested, please look it up. It can be pretty handy. (Of course, some coding rules you may be subjected to may forbid its use, just like they would generally forbid any fancy preprocessor stuff.)

In your example, meant to work with earlier versions of the C standard, there are a couple issues.

First, and this is minor (due to a quick typing from your part) is that "unused" is undefined? I get your point, such C functions would require a dummy parameter to make use of variadic parameters, but the passed parameter could be just anything. I would write this instead:

Code: [Select]
#define cppclone(...)   cppfake(0, __VA_ARGS__)
then the cppfake() function could be declared like so:
Code: [Select]
xxx cppfake(int unused, ...)

The main problem with this is that there is no means of passing the types of the expected parameters to the function. To use variadic parameters in C, you need to know the type of each parameter, and their number. The well-known printf() does this through the format parameter. There is no way around it. You can't auto-detect the variadic parameters. So this approach would not be usable.

Supposing you find a way (through the preprocessor) to pass the types and number of parameters in a transparent manner (good luck), it would be so horrendous and bug-prone, bypassing all compiler type-checking, potentially doing very nasty stuff to the stack... eek. And being very inefficient, preventing the compiler to do a whole range of optimizations.

All this could be fun to discuss in a separate thread, but promoting funky (or borderline desastrous) C constructs in a thread that was meant to be about learning C properly is definitely not a good idea IMO.

As one of the users said, "I can write C in almost any language" or something.
And now it's evolving into "I can write C++ in almost any language" :-DD
« Last Edit: October 26, 2019, 12:41:11 am by SiliconWizard »
 

Offline dunkemhigh

  • Super Contributor
  • ***
  • Posts: 1459
Re: Good C programming books
« Reply #42 on: October 26, 2019, 07:22:38 am »
Quote
I would write this instead:

A case of fingers getting ahead of brain. Your expansion is how it should be, yes.

Quote
The main problem with this is that there is no means of passing the types of the expected parameters to the function.

Indeed! I was aware of that but left it as an exercise for the reader to complete :)

However, it should be born in mind that this isn't intended to cover all possible circumstances. Even in C++ you still need to write the handlers before it would compile. Having said that, I can't off-hand think of a suitable handler for the cases where you might pass, say, an int or pointer.

Quote
it would be so horrendous and bug-prone

Yes. I wouldn't recommend it! In fact, I wouldn't have bothered thinking of it were it not for the checkmate comment  >:D
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 3045
  • Country: us
Re: Good C programming books
« Reply #43 on: October 26, 2019, 08:42:45 am »
I did consider that in the old days, you could do:
Code: [Select]
int cppfunc(arg)
    void *arg;  /* accept any type of argument, maybe */
{
    PORTB = (int)arg;
}

int main() {
    cppfunc(1);
    cppfunc(PORTB);
    cppfunc("test");
}
But it was such a bad idea that I didn't mention it.  (you CAN still do this.  Don't!)

 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #44 on: October 26, 2019, 02:39:23 pm »
Some stupid guys at a company that does not even deserve to be mentioned, defined five layers of define of define of define of define of WTF, resulting a mess, and they ask money to tell you what WTF should be equal to what, with which details and consideration.

 :-DD
 

Offline legacy

  • Super Contributor
  • ***
  • Posts: 4309
  • Country: ch
Re: Good C programming books
« Reply #45 on: October 26, 2019, 02:40:36 pm »
I am on a piece of code with five level of #define of #define of #define of #define of #define of ...

... what? I am lost  :-DD 
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #46 on: October 26, 2019, 02:45:35 pm »
I did consider that in the old days, you could do:
Code: [Select]
int cppfunc(arg)
    void *arg;  /* accept any type of argument, maybe */
{
    PORTB = (int)arg;
}

int main() {
    cppfunc(1);
    cppfunc(PORTB);
    cppfunc("test");
}
But it was such a bad idea that I didn't mention it.  (you CAN still do this.  Don't!)

It's 1/ limited to a fixed number of parameters so doesn't fully address the question, 2/ going to do nothing like what the user probably expects, and 3/ the compiler will spit out warnings for parameters with any other type than a pointer, unless you explicitly cast in the function call, which would look ugly and certainly not "transparent" as far as passing any type goes. So first and second calls will yield warnings. And no, ignoring warnings is definitely never a good idea either.

For 2/, your third call is just going to issue a write to PORTB with the truncated pointer value of the string, which would certainly do nothing useful here...
« Last Edit: October 26, 2019, 02:48:32 pm by SiliconWizard »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #47 on: October 26, 2019, 02:46:29 pm »
I am on a piece of code with five level of #define of #define of #define of #define of #define of ...

Could you post the chain of 5 #defines so we can have a laugh?
 

Offline legacy

  • Super Contributor
  • ***
  • Posts: 4309
  • Country: ch
Re: Good C programming books
« Reply #48 on: October 26, 2019, 05:29:15 pm »
Could you post the chain of 5 #defines so we can have a laugh?

it's spread among several files. In the top header file, there are defines depending on #ifdef #else whose conditions are grabbed from the usual Kconfig mechanism with a simple #include "config.h" autogenerated according to the the user choices done on the menu config, but when you look at what they define, things go deeper into other includes , which only partially define other things, defined in a sub-layer, and again the same, and again the same, and again the same, like a tree which grows from roots to trunks and leaves

Grep says this stuff goes deep from the top to something like 25 files involved, whose low level is practically impossible to be read because there are too many branches and I am not able to follow.

In my case, I counted 5 layers of defines, but I am not really sure that I am observing the right code. I mean, what GCC actually compiles.

Devs must have lost their head for having made this, or they just want to be evil, masters, and mistresses of evil

Because this is really evil, and dark  :-DD


:palm: )
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 3431
  • Country: fr
Re: Good C programming books
« Reply #49 on: October 26, 2019, 06:22:24 pm »
Oh well, this kind of monster often grows from a code base 1/ maintained by different people using different styles and 2/ meant to be built with many different configurations on many different platforms. Handling that cleanly is hard.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf