I want to learn C programming with a goal of doing embedded with rust. Hopefully that makes sense.
I got a book “learn c the hard way” and it actually recommends doing python first. what do you all think?
I understand concepts of C and programming. I have been reading a bit here and there at random, but I’m trying to nail myself to finishing a book or course so I can stop waffling. I have not done much actual programming.
If you haven’t done any programming, then whatever you learn is going to be a learning curve.
C relies on concepts like pointers (e.g., you can’t even process basic types like strings or arrays without dealing with pointers) which is a little more advanced and not ideal as a FIRST language. You can do it, but you’re diving into he deep end a little bit and the memory allocation errors, pointer errors, etc. are just going to make things harder starting out. Even worse, I found pointer dereferencing and declaration syntax quite confusing in C starting out.
Even in the olden days when I was a lad, we had BASIC or PASCAL (now Delphi) or other “safe” languages that shielded you from the complexity of pointers and manual memory management.
Modern safer languages to learn the fundamentals with would be essentially almost anything else.
perl, python, javascript, java, etc.
I would agree - Python wouldn’t be a bad modern day starting point. It’s useful for real world stuff, and will allow you to focus on data structures and algorithms rather than getting continually screwed by memory management errors and crashes starting out. With C, you’ll be fighting the compiler/language syntax, etc. rather than learning the fundamentals of writing good code.
Essentially if you learn python today, it will still be useful even after you learn C - for non-performance critical things that NEED TO BE SAFE. because it holds your hand a lot more and protects you from yourself.
C is analogous to a band-saw or bench grinder, etc. with the safety guards removed. You can probably do a lot more stuff why it, including dodgy stuff that may result in permanent injury or death.
I haven’t worked with RUST before (Have coded on a mud with C though) - but I’d suggest even RUST might be a better starting point than C? I.e., if the end goal is rust, going straight to rust would be better than doing C first perhaps?
edit:
2 minute look up on rust - it is type-safe. this may seem like more work starting out, but you’ll get compiler feed back that you screwed up which is far easier to deal with than the alternative (c) just happily doing what you ask of it and resulting in aberrant behaviour (code will do what you told it to do, even if it is quite wrong vs. what you intended to do).
Whatever language you learn first, I’d suggest something type-safe.
As you’re starting out, this is what we mean by type-safe:
The general advice to learn python first can be applied to pretty much any language. Make sure you have a friend that has programmed before.
Python is pretty easy to get started in and learn all the basics, but in 2024 I wouldn’t put it as my top language, especially not for embedded. Lua is possibly a much more useful language here, but Python isn’t exactly bad.
C isn’t that bad to learn, but C also does not give you anything for free. At the base, C is only about calculations, arrays and memory manipulations. And arrays are just a well-sectioned piece of memory, too.
In C you have integers and arrays (oh, and floats but those are close to useless for embedded). No strings, no containers, no helpful ** operators for exponentials. Only raw memory, pointers, and numbers. Which is both kinda terrifying and liberating once you realize this.
My advice is to start learning about the fundamentals of programming before you tackle C, but you can definitely learn C from scratch too. Just make sure you have a good teacher.
One of these days I really should write a hands down C course for beginners…
As someone who started out with a couple of decades of C programming and then discovered Rust, I think learning C first, with all its manual memory handling, and then Rust makes a lot of sense. Why? Because you will have an absolutely miserable time with Rust’s borrow checker otherwise.
Rust is amazing (it’s what C should have been from the start IMO) but even though I understood why the borrow checker screamed at me all the time learning it was still a hair-tearing, infuriating experience at times. Still, since I understood well the underlying reasons for its rudeness I could use it to re-think my code and actually became a better programmer from it. Today, I program C as if it was Rust, more or less.
Python IMO is a fun tool for learning how to program, but since there’s no compiler to guide you (and no type safety) Python is really a horrible choice for any production code - again IMO. (Not that anybody cares…)
I redid my posts to be in one block sorry if that’s confusing at first.
Python is on my list because I hear its easy to prototype with. which is important to me and if its what I need to do to get to rust no time wasted.
“learn C the hard way” actually brings up all these type safe issues saying that C does exactly what you tell it to and with little no warnings, it also goes into how the undefined behaviors are actually a huge problem with this old, and at times impossible to make safe language.
So I understand what you are saying. Thanks, it helps to confirm what I have hear but also gets my expectations about the language properly set.
The book says that C and its faults are going to be used as a teaching tool to be able to overcome these and learn to be better. so I see the point of not starting with C, as to not double down on struggle with more struggle. I do want to do C before rust, as I have hear the difficulty of Cs memory management and the skills learned from that help with rust in some way. Also C is used so much still in embedded I need it no matter what.
I would read that course . So, You should!
As for learning the fundamentals of programming I have been doing reading and have lots of material so I understand at least enough that most everything you and Thro have referenced did not go over my head.
I have actually read some olds posts you made about C here in the forums when I looked the topic up before posting.
I do not have anyone individually or a teacher per say but there are lots of communities I can pop into to ask for help. I will manage my best with that.
I did not know that foats would not be useful in embedded. will look that up!
wow a man/woman who has tread the path I am about to set myself down how cool.
you articulate why its important to learn C memory management well, thank you. That’s exactly what I am trying to accomplish
A coworker does his concepting in python since its easier to get it typed out then they pass that through an LLM to convert to rust. He has the know how to make that work so I would not do that but makes it seem like python is a more useful tool in that context.
You can do it, certainly. But yes, C is basically starting out on hard mode. On one side it will force you to learn the fundamentals of memory management, pointers, etc. But on the flip side, what’s probably more important and applicable across all languages you may program in are algorithms and data structures and fighting the compiler and memory management bugs at the same time is going to make life more difficult to learn those.
That’s all
It’s a shame pascal has fallen so far out of favour (in the late 90s it was deemed not performant enough vs. C ,and in the late 90s software was really pushing the boundaries of what CPUs were capable of - we were on the cusp of doing interesting things, but the hardware wasn’t quite there yet).
It’s the first “real language” I learned (very first being basic). It’s a really really good blend of nice, readable syntax, type safety, and dealing with compilation, etc. without being screwed over by subtle memory management errors.
But, if you are seriously motivated and want to LEARN C right fookin now:
Grab a pen and a steno pad then complete the exercises.
Pointers are simple, * and & is a mind fuck that took a solid day of pontificating before I know it backwards and forwards as you have to account for order of operations.
disclaimer if you’re pedantic: you’ll quickly learn only the master pros use C in such a way as to follow strict interpretation. Most programmers do not rely on C’s programmatic order of operands in line interpretation and instead choose to break up commands.
It’s predominantly graphics programmer sorcerers, and embedded security maintainers that cannot waste clock cycles who make one liners that take unironically 6 hours of research to fully understand.
But if you simply work through the entire book by hand (I did it in 6 days), you’ll be a better human afterwards.
I learnt to program in Object Pascal / Delphi, where all the concepts I learnt were progressive and really intuitive. But of course it has limitations at the language level itself. It’s too rigid in my opinion. Afterwards I moved to C and to Java + C#. It was a seamless transition as the concepts from Object Pascal were easy to translate to C/C++.
Not sure if it would be unpopular nowadays but that’s the path I would follow:
Object Pascal - to the point where you handle pointers (get it) and a little bit of UI
Then C, C++ (to understand how to “manage” pointers).
Rust
The way I see Python, it’s like a side language. It lets you do things quick and dirty, but by no means it should be your main driver, and it could be learnt in parallel to any of these. But that’s my personal preference.
PS: I don’t use Object Pascal anymore - it was a more civilized tool for civilized times
A few pointers for all aspiring programmers in general, and new embedded C programmers in particular:
0x30f15e14
0x4dedf4c3
0x39581303
… Oh. OH! You wanted THOSE pointers. Well, I have a few of those too:
Programming is a trade and compilers and editors are tools. Be a good craftsman. Learn your tools, and make sure you spend plenty of time using them - e.g. write a ton of stupid code, and learn why the code you wrote is stupid and make v2.0 that is a bit less stupid. It is ok to write stupid code, that’s the best way to learn.
Floats are the devil. Never rely on them unless you have to. It will come back to bite you hard when the unreliable race condition bugs keep happening for no good reason. There are a lot of good reasons here, but direct comparisons like if float_a == float_b is just the tip of the iceberg.
C23 finally introduced the nullptr type and value. Please, please for the love of good and all that is holy, use nullptr in all your code, rather than NULL.
NEVER ever increment pointers directly or perform any sort of calculations on pointers. At best the code is harder to read now, at worst you just introduced memory leaks and buffer overflows.
Instead of using the built-in types int, char, long et cetera, always do a #include <stdint.h> and use the types uint32_t, int64_t et cetera. This removes a ton of ambiguity and allows you to take full control of your code on a bit level. I wish that stdint.h was included by default, but it sadly isn’t due to backward compatibility reasons.
Just knowing these 5 points, I feel a C dev of today get a ton more out of C. Then of course, learn what a linter is and also do learn the toolchain not just the code (gdb, make, gcc et cetera).
Yes I would enjoy learning for the sake of the usefulness of it.
truely I am sure I will be unable to focus so much on embeded that I only make things there. once I see the possibilities
I have that actually, and I started reading it. I have heard that its a bit old now and while the foundations are good somehow its dated and you have to watch out for that in some way. it put me off of it a bit. I started to look for newer material. so I can at least learn modern c then look back on some older material.
what do you think?
I know its still relevant just keep reading that its older.
woh thats intense XD
Ill have to pick it back up for sure. I really want to get good at C It does not seem like something I will hate wrestling with.
I have only heard of Pascel by name so I will look into that.
I have begun to feel that exact same way. its great for some quick and dirty but never more then a prototype or proof. Temp solutions are often permanent as we all know lol
I got it guys XD am I with it now.
I have also heard this many times in my books its really hit home the more I hear it so thanks, I need to get started and not to fall into the eternal research phase.
Those are great pointers genuinely it builds on some stuff I already started learning and adds some new stuff.
I have heard of the badness that is null and memory leaks by doing stuff to pointers that are not there and just modifying memory in horrible ways.
where do you learn about new things in C like that?
Looking up all these new things you have shown me! THANKS
MAKE and GCC are things already on my radar to learn about but also adding gbd and cetera now thanks doubly
thankfully some of the books really push make as being awesome.
That sounds like a terrible idea, python and C are so different that learning python will just end up teaching you many bad habits that do not apply to embedded C and Rust.
If you want to do embedded, I’m sure there is some book on embedded development with arduino that will be vastly more helpful
BASIC (8 bit computer, would have been like 6-10 years old. Specifically Microsoft Basic on the Tandy CoCo 2.
Turbo Pascal 6/7 with object support (mid-teens - DOS)
inline assembly x86 into Turbo pascal to mess with VGA hardware (late teens) - yeah, I was messing with x86 assembly before C! - mostly limited to messing with interrupts, fast memory copies (blitting for sprites, etc.), directly accessing the VGA memory segment.
C to work on a MUD (early 20s) - Linux
As I may have said above, I really miss / like pascal. It can use pointers, but they seem to be a lot easier to understand than in C due to the way they’re declared and referenced. Data structures are easier to define and understand too. Basically similar to C but “easy mode” - you can focus more on learning the concepts rather than dealing with the terse and cryptic language that is C.
Sure it has limits but today… probably not so much. We have 32 bit flat memory models (no more segment registers with 64k segments), etc.
Most of the limits of Pascal back in the day you could “escape” with inline assembly (at least in Borland/Turbo Pascal which enabled inline assembly for functions and procedures or even mid-procedure).
It was so nice to use Pascal for all the low performance requirement stuff (dealing with files, etc.) and then assembly for graphics and sound - all within the same file in the same IDE
Yeah - I think Pascal should have its niche in education. It is so well structured compared to every other language to the point that it REQUIRES you to be structured. From an academic purpose this is great! With that being said, its limits show up pretty quickly, as that structure becomes quire rigid compared to C++.
It’s such a lost art nowadays… I remember that a while back there was a lot of malware being developed in Delphi (a modern Pascal compiler for those that don’t know) that anything that was produced by the compiler was flagged as malware by default.
I place Pascal in the same category as Ada - good language with a rich history, but today there are better / more flexible options. If you learn Ada, VHDL becomes really easy too, and the fact that it forces you to do things in a specific way is quite a valuable experience. I learned to stop doing pointer arithmetics with Ada, for instance
I own this book and really appreciate it’s direct repetition to all learning. I would double-down on pushing this book and its exercises to completion. I also own Learn Python the Hard Way, and equally enjoyed working through it. There are also associated videos as I recall - best of luck!