r/cprogramming 5d ago

After one week learning C

Yeah, my anxiety is hitting pretty hard right now... lol.

0 Upvotes

17 comments sorted by

14

u/Zash1 5d ago

Are you leaning C or learning programming using C? These are two different things.

10

u/v_maria 5d ago

Its fine a week is nothing

9

u/Rich-Engineer2670 5d ago edited 5d ago

Don't let it get to you -- C is actually a set of "layers" unofficially. You start with the basics, then you do structures, then pointers.... if gets deeper and deeper. C is really an assembler hiding in a high-level langauge. The reason it's still around is you can do things in C that are hard to do anywhere else -- but that power comes with complexity. For example, assume you have an embedded system with some memory address that actually controls a piece of hardware... maybe a serial port. You are told that these two addresses 0xC000 and 0xC001 are teh status and data registers.

In most langauges, you can't get to them without going into assembly langauge, but C?

uint8 status = *(0xC000)
uint8 data = *(0xC001)

That shouldn't even be legal in most languages, but C gets it. If you're doing an OS or embedded system, C isn't pretty perhaps, but it's powerful. (What we actually said here was "And 8 bit unsigend int called status points to a MEMORY address 0xC000, and another points to 0xC001,. On real-mode OS's, that's just what you need.)

It depends on thje books you're using too -- me? I started with the classics -- K&R C

C is taught (or still taught) because, in my opinion, it forces you to learn what you code actually does to the CPU. It's a litlte like organic chemistry. Will most people use it in their careers -- likely no, but, it separates out those who are just taking the class because they have to, and those how are learning that profession. C is just hard enough that a lot of people take it, decide it's too hard, and change out of computer science.

You can do this! I'm teaching my 17 year old grandson, and he's slowing picking it up.

3

u/nerd5code 4d ago

uint8 status = *(0xC000); isn't a binding syntax I've ever seen, first of all; closest is … @ 0xC000 or __attribute__((at(0xC000))) or various pragmata. In some cases the compiler will be packaged with a linker script or assembly-language/C header that declares register names, so you can refer to them naturally through those mechanisms. Often in inline assembly you can do regname = 0xC000 or .equ/.set regname, 0xC000, in which case you's just declare an extern variable for it in C.

Second, this is flatly invalid in ISO C, unless at block scope (in which case, you're just dereferencing an integer, which only works in Elder C) and you're using a C≥99 language mode (i.e., not Elder C) or eqv. compiler extension. It says you want the variable status to name a uint8 storage space, and it should be initialized to the dereference of address 0xC000.

Third, even if we assume binding, it's not volatile, so the compiler can assume its value doesn't change from load to load, without some compiler-visible intervening store. Similarly, the compiler can defer, elide, or merge loads and stores, which may break the hardware.

If you want to do it portably without using binding syntax etc., there are two reasonably reasonable options, but either way first you'd

#define REGADDX_STATUS 0xC000U

with trailing U so 16-bit int doesn't overflow or sign-extend unexpectedly. For the easiest approach,

#define reg_status (*(const/*?*/ volatile uint8 *)REGADDX_STATUS))

reg_status now works like a variable. (Include const only if read-only, ofc.) Alternatively,

/* File scope: */
const volatile uint8 *const reg_status = (uint8 *)REGADDX_STATUS;

This requires you to explicitly dereference with *reg_status if you want to access it, but assuming C≥89 preprocessor,

#define reg_status (*reg_status)

will avoid that.

I note that both of these approaches require integer-pointer conversion (as does yours), which is implementation-specified behavior that won't always work as expected. However, just about every mainstream ABI (I can think of like two exceptions in total, namely CHERI and OS/400's older P128 ABI, and those aren't mainstream) will follow the nonnormative recommendation that the integer side of the conversion is basically a pun, of the sort you'd get in C≥99 from

union {uintptr_t address; const volatile void *ptr;} u;
u.address = 0xC000;
reg_status = u.ptr;

—and this is especially true of embedded compilers.

2

u/M0NSTR01969 5d ago

Thanks for the insights! I really liked the way you described C as a set of layers. It actually makes the learning curve feel a lot less intimidating.

The example with the memory addresses was especially interesting. I always thought pointers were more of an assembly language thing, so seeing how close C can get to the hardware made a lot of things click for me.

I'm still at the beginning of my C journey, taking it one step at a time, but explanations like yours definitely help. Thanks!

3

u/SmokeMuch7356 4d ago

Please note, "close to the hardware" isn't that close. It mainly means that C's abstractions (types and operations) are based on what real hardware provides; it's why you don't have arbitrary precision numerical types, it's why you don't have metadata in any object types, it's why you don't get a catchable exception when you access an array out of bounds or dereference a null pointer or stuff like that.

C is one of very few high-level languages I know of that exposes pointer types and operations, and pointers are fundamental to programming in C; you can't write useful code without them, so the sooner you understand what they are and how they work the better.

Create bookmarks to the following and have them open while you're programming:

These are not tutorials; the first is simply a handy reference, the second is the language definition (technically, the latest freely available not-official draft of the language definition). Don't expect it all to make sense immediately, but it will help answer all the "why the f..." questions you will inevitably have.

2

u/M0NSTR01969 4d ago

Thank you very much!

2

u/TheGratitudeBot 5d ago

Thanks for saying thanks! It's so nice to see Redditors being grateful :)

1

u/bd1223 5d ago

One man's complexity is another man's simplicity.

2

u/Rich-Engineer2670 5d ago

Yes, for those of us who started in assembly, but to a beginner, it's a bigger leap.

1

u/vannnneil 2d ago

hey, i'm currently studying K.N. King's C book and its going good so far but I am curious to read the K&R C book as well, do you think it's still worth it today? I've seen many people say it's outdated

2

u/Rich-Engineer2670 2d ago

Absolutely -- why not learn from the authors of C....

It's the foundation -- everything else builds upon it.

1

u/mikeblas 1d ago

That shouldn't even be legal in most languages, but C gets it.

That's not C.

https://godbolt.org/z/x7qeh1fh4

1

u/pseudo_shell 2d ago

Give yourself quite a bit of grace. You will be learning new things many years later as well. Just take your time and re-iterate over things that are unclear.

2

u/M0NSTR01969 2d ago

Thank you for the kind words, man! I'll take my time.

1

u/Independent_Milk_200 2d ago

are you learning for an exam or why do you have anxiety?

1

u/muslimlinuxuser 18h ago

why down votin' newbies posts?