5 ms·
(I upvoted you, I think your question is fine FWTIW) Sadly, yes. Universities have moved away from teaching C. In ancient times, when I went to school, you'd
by luckydude 9y ago
(I upvoted you, I think your question is fine FWTIW)
Sadly, yes. Universities have moved away from teaching C. In ancient times, when I went to school, you'd start with an intro class in Pascal, then you'd take a data structures class in Pascal, and then you'd take some harder class in C.
About half of the people in the C class would drop out of Computer Science when they hit pointers. As someone who gets pointers pretty much instinctively, I didn't get it, the concept seemed really intuitive to me. But apparently that's not true for everyone, some people really struggle with it.
I think it really doesn't help that CS has moved away from C as a teaching language. C can be viewed as a pleasant, portable, assembly language. As such, it lets you "feel" the bare metal, much more so than a scripting language like Python or Javascript.
- pjmlp 9y agoWe had pointers already in Pascal.
- throwaway18917 9y ago> C can be viewed as a pleasant, portable, assembly language. Do I have to buy what you're on from some guy on the street or is it available as a prescription? > As such, it lets you "feel" the bare metal, much more so than a scripting language like Python or Javascript. C hasn't been bare metal since the PDP-11. There are like eight layers of abstraction between char *foo = "bar"; and the "bare metal"; I don't know why people are desperately clinging to this "C is basically portable assembly nonsense".
- akubera 9y agohttps://godbolt.org/g/q01z7n https://godbolt.org/g/q01z7n I'm not sure what you mean by layers of abstraction (type checking? optimization?) but C code often does have a pretty straightforward translation to assembly. Perhaps you had a bad experience and can clarify what you mean?
- chousuke 9y agoEight layers? That made me curious about how many are there really, though? My understanding is rather vague at this level, though hopefully good enough to know when I need to look deeper. So the compiler is obviously one layer. Then there's the assembler and the linker. Does the C runtime count too? You think you have a "string", but it's actually just an address to a (hopefully) nul-terminated chunk of "contiguous" virtual memory. If you wanted to read the first byte of that array, it would first go through the OS's virtual memory system, so that's one rather large abstraction. (I'm lumping in the hardware's virtual memory support here, too) Then when you actually access a piece of "real" memory, there are a number of caches between your data and the request to fetch it. And what about the DRAM itself? Can it access only a single byte of memory at a time, or is that too an abstraction? Instruction decoding is one or two layers at least, since chances are the processor doesn't actually execute x86 opcodes directly. And when you run out of software abstractions, how many levels of abstraction is there in the actual hardware? I only have vague ideas of what actually happens at this level, and whenever I stop to think about it, it's pretty amazing our software stacks work at all...
- deleted 9y ago[deleted]
- e12e 9y agoOddly I find pointers intuitive and easy in Pascal and assembler - arcane and complicated in C. Java (memory model) is also rather difficult to internalize IMNHO - probably because of the complication of "bare" types (eg: int), boxing, pass by reference and some rather muddy default/usual containers/objects/arrays etc. Other than for teaching "an industry language" I don't immediately see much reason to teach C and Pascal - but I suppose the "modern" equivalent would be Python, Cython, C and assembler, followed by haskell/(oca)ml, Prolog and/or a lisp/scheme - with the benefit of showing C interop along the way.
- kazinator 9y ago> Oddly I find pointers intuitive and easy in Pascal and assembler Sure, sixy seven lines of assembly handily beats arcane crap like: obj->ops.tbl[BLAH]->func(obj, &obj->x, arg); Want to take an integer in a register, then add another register's integer multiplied by 8 or 4, and then a fixed offset? Just use LEA (load effective address) and don't comment anything. Let the reader figure out that no pointers are involved.
- emmelaich 9y agoI guess you're being sarcastic but I honestly can't tell. [edit: 99% sure is sarcastic]
- int_19h 9y agoI can't help but wonder if the reason why Pascal pointers feel less complicated because they're more constrained, or because of the syntax, or both. On the constrained part of things, there's no pointer arithmetic, and in Standard Pascal, there's no "address of" operator at all - a pointer can only point at dynamically allocated memory block, not at global or local variable, or some memory location inside another block. Consequently, there's also no pointer arithmetic. This is sufficient to make linked lists and other similar data structures, but also makes the concept much more opaque compared to C (i.e. it's less obvious that it's really a numeric address). On the syntax part, I think the big problem with C is that the moment you start dealing with pointers, the arcane rules for declarator precedence are in play. Pascal, OTOH, has a very regular type syntax, which in case of pointers is also easier to read - you just read ^ as "pointer to", and so ^integer is "pointer to integer". Same thing for dereferencing - again it's ^, but there you read ^ as "points to", and so a dereference like x^ becomes "what x points to". And there's also no confusion with any other operator, since ^ is reserved for pointers alone, and it has a fairly obvious mnemonic to it.