Notes from Mastering C Pointers
The first set of notes are from the second edition, which I read first. I didn’t start taking detailed notes until I fully realized how terrible the book was.
- "The construct c[0], for instance, is a bona fide variable." (pp. 18-19)
- "A pointer is a special variable that returns the address of a memory location." (p. 27)
- "object value" is used regularly in Ch. 4 to refer to just the value of a basic type.
- "Both programs also contain another value of 43. This is the constant that was written directly into the program." (p. 29) — I have no idea what this means.
- "As with previous pointer declarations, the indirection operator is used when declaring a char pointer." (p. 42) — Seriously…
- "The strcpy() function copies a string constant into the bytes allocated to the array." (p. 42) — Does this mean it only copies string constants?
- "Next, p is assigned the address of the array." (p. 42) — Well, sorta…
- The previous three excerpts are consecutive in the text. Yikes!
- Code:
p = a;
. "Therefore, a returns an address to p." (p. 42) —>_>
- I believe that the author thinks that integer constants are stored somewhere in memory. The reason I think this is that earlier there was a strange thing about a "constant being written directly into the program." Later on page 44 there is talk about string constants and "setting aside memory for constants." I'm wondering now…
- Author is also consumed with the notion of saving memory and time, but I don't think he is very good at it.
-
"Therefore,
"DATA"
is a pointer." (p. 44) — Holy shit. - This should have been called "Mastering C Pointers on my particular DOS machine" because everything is nauseatingly platform specific.
- He regularly refers to an expression as "returning a value."
- The text regularly touts micro-optimizations that are just junk. Avoiding a variable in a for loop, not declaring local arrays, and so forth. What a crock.
- "…(remember, the array name becomes a pointer when used without the subscripting brackets)" (p. 56)
- "…while a pointer, as always, is a special variable that holds the address of a memory location." (p. 57) — Still wrong, but slightly less wrong.
- The discussion of multi-dimensional arrays on (pp. 58-59) has to be read to be believed.
- He claims that
char *a, far *b;
is "the more obvious method of making these two declarations" (p. 71) versus putting them on two lines. (Note: afar
pointer is something used on DOS to reference memory outside the usual 64K.) He makes the argument earlier that this sort of thing is good because it saves typing. - "If you are using a fast computer you won't be able to detect the speed difference in the two methods, but it is quite significant." (p. 68) — Uh… didn't you just kind of defeat your own point?
- He says that working with decimal is "cumbersome" for memory addresses (p. 66), yet most of his examples use decimal memory addresses.
- "A char pointer expects a return value of type char" (p. 73) — The hell… (the whole paragraph is full of this crap.)
- At one point he says how errant pointers can result in your hard drive being wiped, but they proceeds to use a ton of examples with specific memory values. You'd better hope your machine is the same as his.
- "The first rule of thumb when dealing with declared pointers is to give them something at which to point." (p. 79) — Not really a rule of thumb…
- The program on p. 81 is wrong. It doesn't allocate enough memory to hold the full string and hence, overwrites something.
- After the same program, it says, "The strlen() function returns the
total number of bytes in the string including the NULL [sic]."
- From the C89 spec: "The strlen function returns the number of characters that precede the terminating null character." (S4.11.6.3)
- From the Borland Turbo C 2.0 Reference Guide: "strlen returns the number of characters in s, not counting the null-terminating character." (p. 367)
-
char= a[60000];
(p. 84) – DID YOU TRY ANY OF YOUR GODDAMN CODE - "…because the space allotted to the stack is just not this large." (p. 84) — First mention of the stack, afaik.
- The program on pages 84-85 is insane. A true work of WTF.
- malloc'ing raw sizes without using sizeof(). You are truly fucking up the lesson here.
- The whole array isn't even initialized to the mystical 88 value. It misses the last element.
- It will loop forever since the loop iterator variable is y, yet x is incremented
- THIS IS THE SECOND EDITION FFS. Ostensibly, someone checked this.
- "…the more common *(x + 2) offsetting syntax that is often used with declared pointers." (p. 86) — Not so sure about this one.
-
"
*a++
: Here, we are actually changing the address of the pointer." (p. 89) — Staaaaaaaaaahhhhhhhp. You're changing the value of the pointer, goddammit. - The discussion on pages 90-92 is mind boggling. For one thing, it's the ultimate in premature optimization. If I'm learning pointers, why do I care about writing and saving screens? Like, literally saving the text on the screen to a file. Also, it only works on his machine. It encourages the reader to worry about things that have no bearing on learning about pointers.
- And the discussion about calloc continues the insanity. He touts the benefits of it taking a unit size and that it zeros out memory. Yet, if you're concerned about micro-optimization bullshit, calloc is not your friend. Furthermore, he fails to talk much about malloc and sizeof! He spends literally a paragraph on free (p. 94), calling it a "side note".
-
malloc(400 * sizeof(int));
"Here, the argument to malloc() is a mathematical expression." (p. 94) — My head can only shake so much… - All of chapter 8 is rooted in misunderstanding and is wrong on so
many levels.
- It argues that
int square(int x) { return x * x; }
is a bad function because it can't square two numbers at the same time. (The function is called "useless".) - It is eventually replaced with a function that takes two
int
pointers and squares both. It is still calledsquare
. - We then get the
newprint
insanity that I'm still trying to figure out. It doesn't work in any C that I've ever seen or heard of. It aims to demonstrate howprintf
works, in principle, without using the...
argument. It's absolutely fucking insane. - Pointers to functions are seen mainly as a way to obfuscate your program. /"A pointer to a function serves to hide the name and source code of that function. Muddying the waters is not normally a purposeful routine in C programming, but with the security placed on software these days, there is an element of misdirection that seems to be growing."/ (p. 109)
- The infamous
combine()
function shows up here: /"The program declares two char arrays, a char pointer, and *combine() to be a function that returns a char pointer value."/ (p. 112) — Dude can't even get the function name right. - (Speaking about the function
char *combine(s, t)
[sic]): "Upon return, this function will equate to a char pointer." (p. 112) — Honestly, should I be surprised? - He directly contradicts himself from earlier by saying that
strlen()
on the string"horse"
will return 5 (p. 112). Earlier, he said that it counts the null character, so this should return 6. Two wrongs did make a right. -
"
return(r);
[from combine()]. This expression is the obvious and correct choice." (p. 113) — He honestly believes this is a good idea. - "Within the function, a pointer to the first argument can be used to access all of the list [of arguments]…" (p. 114) — OHMYFUCKINGGOD.
- It argues that
- As I try to understand the mindset of the author here, I'm pretty sure he thinks he's in a BASIC world where there is no actual function calling. I'm fairly certain at this point that he believes that any variables declared in functions have specific locations in memory for the duration of the program.
- I'm apoplectic at the thought of how much damage this book has caused.
- /"Since these functions are actually separate programs that have no relationship with the calling program, other than through the arguments that are specifically passed back and forth, pointers provide a direct means of communication."/ (p. 115) — Properly parsing and critiquing this sentence would rid me of my sanity.
- Still 40+ pages to go, and he's going to cover unions. I'm fucked.
- "These opinions are arguable but one fact is certain: C is an extremely popular object-oriented programming language" (p. 3). "While ANSI C is not an object-oriented language…" (p. 117)
- Missing a double quote in the program on p. 118. I wish I had the disk that came with this…
-
"The int and double members are assigned values, using the same
operator." (p. 118) — The operator?
=
. It sounds so special. I mean, really, who says this. - One thing this author does is build on a couple of examples with some concepts, then completely change the example when fleshing out the concept even more. He says the book is meant to teach in a conversational way, yet it goes out of its way to confuse, even ignoring the plethora of garbage in it. So even in its own world it's baffling.
- /"When dealing with ANSI C structs, there is no problem with individual access of each element. However, when the structure as a whole is to be passed as an argument, a pointer to the structure is required. Pointers to structures have their own connective operators that allow for access in a convenient, shorthand manner. Trying to access a structure via a function call that does not include the structure address is an error and will result in garbage writes and reads from the structure."/ (p. 121) — I don't have a stiff drink in my hand but if I did, I would down it now. Is he trying to say you can't pass structs by value? I can only think of the Ralph Wiggum line (where he's using a computer, no less): "I'm learnding!"
- Aaaaaannnnnd now he's going to talk about using offsets to get to fields in a struct isn't he…
- Holy Mary Mother of God, he's telling people how to allocate storage for a struct by manually counting the bytes… (p. 122)
- There is a program introduced on page 122 with "The following program details this allocation of structs", but the program does nothing of the sort.
- "Without the struct variable [declaration], the struct pointer has no size (is not initialized)." (p. 124) — Wow. This guy has no idea what he's doing.
- More proof: /"However, if a struct pointer is declared, there is no automatic allocation as is the case with any other type of declared pointer."/ (p. 125) — Automatic allocation of what? What!? For Christ's sake, a pointer is a variable. If you declare it, space is set aside for the pointer. Nothing else. What in the blue fuck is he talking about here?
- He calls struct definitions "struct templates".
- At least he used sizeof() to get the size for the call to malloc!
- Oh god, he's calculating it himself! DANGER ZONE.
- He seemingly has no idea about the %x printf format specifier.
- This guy's in for a helluva surprise when he tries to run these programs on anything that requires non-trivial byte alignment.
- After a program that prints the address of structure elements, showing they are stored using byte alignment: "This proves that ANSI C structs store their data in sequential blocks of memory." (p. 128)
- Now we're writing directly to structure elements with offsets. Wonderful.
- "In ANSI C, a struct is a collection of intrinsic data types that result in a single, derived data type." (p. 129) — Evidently, a struct of structs is not possible.
- "If the ANSI C union sounds more and more like a specialized pointer, that's because it is." (p. 133) — Hard to find worse advice than this.
- Program is shown that allocates space and uses pointers of different types to write to that space (it's meant to emulate a union, er, "specialized pointer"). Then this: /"While this works as well as the union example, this is true only from an execution standpoint. Obviously, using a union is more efficient, because all of the storage and addressing is handled by the union declaration."/ (p. 134)
- Incidentally, all the union examples up to this point write into each field for some pointless reason.
- "Structs can also be members of other structs or of unions. Union members may even consist of other unions." (p. 136) — Oh good, struct of structs is possible.
- He keeps saying variables have "exclusive addresses". I really think he doesn't know what the stack actually is.
- Program on page 142 assumes a pointer is an int and assigns a char pointer through an int pointer. Fffffffffffffffuuuuuuuuuuuuuuuuu
- It's clear he's never encountered pointers to pointers, but cobbled together some semblance of understanding of the concept. What he doesn't realize is that by talking about them as "pointers to pointers", it's actually more confusing.
- /"In this program
**ptp
is declared a pointer to a pointer of type int. This means that ptp expects to be handed the address of a pointer."/ (p. 145) — "Handed"? Good god. (And it needs to be "handed" the address of a pointer to an int, you idiot.) - The program on page 146 is wrong (like, totally wrong) and even the code snippets from that program in the explanatory text afterwards is wrong, so it's not just a typo. But the worst part is that a previous owner appeared to be trying to understand what the hell was going on. I feel genuinely sorry for that person.
- "At the bottom of the heap in a pointer stack is the ultimate object." (p. 146) — This wonky phrasing comes in an attempt at explaining pointers to pointers, and is the only other place I've heard something about a stack.
- In the summary for the chapter on page 147 he, for reasons that make no sense, suddenly starts talking about lvalues and rvalues. This provides some insight into the mind of the author: he's just picking up concepts and terms as he learns about them and tossing them in without any regard for the reader. This book is pretty much his journal — that somehow became a book with two editions.
- Now the ultimate irony: a chapter on source code formatting.
- This book has the worst code formatting I've ever seen. It's actively confusing.
- /"GIGO (garbage in, garbage out) is a term coined to describe computer output based on erroneous input. The same applies to a human being."/ (p. 152) — ???
- /"In 1984, I began work on CBREEZE, a translator program that accepts BASIC language source code and converts it to C source code."/ (p. 153) — THIS EXPLAINS EVERYTHING.
- Nearly all of his code samples don't match up with the formatting rules mentioned.
- /"You will grasp the concepts of C language pointers discussed in this book and every other phase of C language if you make yourself adhere to the programming conventions outlined here and garnered directly from The C Programming Language by Kernighan and Ritchie."/ (p. 157)
- "However, there are plenty of bad examples of C source code to influence beginners." (p. 157) — I literally laughed out loud at this one.
- "Indentations are always made in steps of five." (p. 158) — Now we know you're a crackpot.
Here are the notes from the first edition. I remark on the differences between the books at the end of each chapter.
- /"Prototyping is a powerful new tool to C programming, but it should used to enhance program efficiency, not to make up for bad programming methods."/ (p. 4)
- /"Programs in this text, for the most part, are written to be compiled using the small-memory-model of [Borland] Turbo C. This is the model that will produce the most efficient code…"/ (p. 5)
- Chapter 1 is similar, but shorter. It doesn't talk about ANSI C, probably because it wasn't widespread at the time.
- He goes to great lengths to say that the address of
x
, for some auto variablex
, is constant. It's the same in the second edition. What isn't clear is what happens when a function is called and returns. There are no programs that demonstrate this in the book that I know of. - The wording around this "constant" is ambiguous, though. It might mean he knows what the stack is, but he sure isn't mentioning it.
- "As one who has learned several, diverse computer languages…" (p. 15)
- And then: /"I became very disgusted in my first attempts to learn LISP, because I had to search my interpreter manual and my technical books for several hours before I finally found the needed function to write to the screen."/ (p. 15) — Something tells me you'd never learn LISP.
- "The largest knapsack is owned by Mr. Double and has eight compartments for holding a double-precision floating-point value." (p. 15) — This is part of a bizarre "Little Man" metaphor to explain addresses and memory.
- "On declaration, an exclusive area of memory, retained specifically for storage of variables, is set aside." (p. 17) — This might be the stack, but earlier he mentions there are regions of memory in MS-DOS that are not used by programs. I don't think there was virtual memory happening on these systems in the same way that we have it in OSes now.
- Page 18 mentions static variables, but only in passing.
- /"Likewise, no two variables will be allocated storage at the same address (again, when dealing with the types of variables discussed at this point.)"/ (p. 18)
- /"If the storage for this variable is allocated at memory location
65514, then this is that variable's 'fixed' address for the duration
of the program. This cannot be changed."/ (p. 18) — Why the
quotes on "fixed"? It wasn't written this way before. Duration of
the program? Is he saying that because the only programs shown are
just what's in
main
? - I didn't realize the significance of the discussion in this chapter the first time around. And it's the same in the second edition. He may be truly clueless.
- No surprise, he doesn't think about EBCDIC. Fair enough.
- My god, the explaination of
strcpy()
on page 23 is a meandering mess. -
"It can be safely said that
x[0]
is a variable." (p. 24) — More brain cells destroyed. -
"The ampersand unary operator cannot be used in a construct of
&x
becausex
is already a pointer." (p. 25) — Note thatx
is declared aschar x[9]
. He proves this wrong later in the book. - "It can be seen that, unlike single-element variables, char arrays offer more sampling variations." (p. 33) — WAT
- Chapter 3 is basically the same in both editions.
- It's around here that I started taking more detailed notes before, so I won't take many more, unless I find points of notable difference, or I find more evidence that supports my theory he doesn't know what the stack is. Or I just find phrases that stand out.
- /"All of the pointers that have been discussed to this juncture have been 'fixed'; that is, they have been inextricably tied to a variable that was declared at the opening of the program."/ (p. 35) — In both editions, but "fixed" is not quoted in the second. Really sounding like he's a "no stack" guy.
- It boggles my mind that he calls it the "unary * operator" when talking about declarations.
- Program in page 53 is wrong. Fixed in 2nd ed.
- "A pointer passes the value of the address it contains." (p. 64) — The writing is beyond sloppy.
- "Bingo! The hammer fell on a loaded chamber." (p. 67) — Mixing the metaphors of Russian Roulette and Bingo. This is like having a conversation with some idiot at a party who insists on telling you how your job works because he saw a video on Facebook.
- Efficiency is his main concern, not comprehension. That tells you something.
-
"If you answered
"SILICON"
, then you are totally incorrect." (p. 69) — Shaming the reader. Good stuff. - "As always, nothing is copied to a pointer." (p. 73) — Does he realize he's just being confusing when he says this shit?
- "Char arrays are used to 'store' data." (p. 74) — Scare quotes? Is he using this ironically somehow? (He phrases it differently in the 2nd ed.)
- Oh man, and he's using them all over the place. Who edited this?
- Chapter 5 hasn't changed much between editions.
- The ridiculous "BANGULAR" example is on page 79. It's sort of fixed in the second edition.
- There is a discussion on small/large memory stuff in MS-DOS in
chapter six that demonstrates what he really doesn't understand: the
division between program and machine. He talks extensively about
using peek/poke operations to write something directly to a memory
location to make a character appear on the monitor. Most of the C
programs in this chaper use something like
char *a; a = (char *) 0xb0000000;
to get a pointer to this space (doesn't work for me, btw). But he's missing the point of the program: to abstract the intent into some artifact that both communicates that intent and can execute it. All he thinks about is the execution. He's a truly awful programmer. - More: he shows the
pokeb
function from Turbo C, used to write to a value to an offset in a segment. Sopokeb(0xb000, 0, 'A')
would write'A'
to the screen (top-left corner?). He calls this "wasteful" (p. 82) and instead usesa = (char *) 0xb0000000
. He really doesn't get it. This is first-year level stuff, folks, and he's adrift in bullshit myths, even for the time. - /"When a C program calls a function, the calling program actually relinquishes control to the function. This takes more time than if the function were actually written within the calling program, proper."/ (p. 84) — I'm still trying to figure out what he means by "program" as opposed to "function".
-
"Similarly, a specification of
%o
will cause 66 to be displayed asOctal 102
." (p. 86) — Only prints102
in my version. - He never stops talking about how the 2-byte pointers (small memory model) is superior in code size and speed.
- Of course, there is zero evidence to show anything he says about efficiency, be it the space or time variety.
- /"If you switch from one [memory model] to the other, it will be necessary to to change the source code slightly when pointer operations that use direct addresses are part of the code."/ (p. 96) — Gee, maybe if you were to use that abstraction idea…
- Chapter 6 is largely the same between the two editions.
- "This is the pointer 'initialization' process and it cannot be repeated too often." (p. 99) — It's fun to parse this sentence.
- The
malloc/strlen
example on page 102 is wrong (same in 2nd ed.). - He says "copying to a pointer" when he really means assignment.
- Program on page 103 is syntactically incorrect. Same error in 2nd ed.
- Program on page 104 uses
<stdio.h>
to the get the definition ofNULL
, but up to this point, it's never been included to getprintf
. - /"If the value returned by malloc() is other than zero, then the allocation attempt was successful and this value becomes a pointer to the allocated block."/ (p. 105) — Pretty sure it doesn't "become" it, it is it.
- The
char a[60000]
example is actually correct in this edition. - Okay, so it's after the
char a[60000]
he says that you can't do this through normal declarations, "because the space allocated to the stack is just not that large." (p. 105). (He even changed the wording slightly in the 2nd. ed., using "allotted" instead.) So I tried a 60000 char array on my MS-DOS Turbo C setup and I had no problems using the small memory model. Maybe I have to configure DOSBox differently, but it makes sense that he could see a problem if your address space is basically 64K. However, even if it is, the program could still work, depending on how memory is laid out. Still, it's not good evidence to suggest that he does know what the call stack is.- I tried an 80000 char array and it didn't fit. The error was "Array size too large in function main."
- Syntax error, program on page 113. (Does he ever check the closing
braces on
if
blocks?) - There is some pure insanity about unsigned chars on page 114. I can't be bothered to quote it all, but I will get this part: "However, this signed char business is one feature I don't like." And you DON'T UNDERSTAND IT. In short, he thinks all chars should be unsigned to make C syntax easier to understand and to prevent problems using -1. (!)
- Chapter 7 is much the same, save for the unsigned char quackery.
- /"While pointers are useful, powerful, and indispensable throughout all phases of C language programming, their capabilities yield high-powered program performance especially when dealing with programmed functions."/ (p. 123) — "Programmed functions"? What's an unprogrammed function?
- Making someone learn from this book would be as ethical as doing another run of the Stanford Prison Experiment.
- Program on page 128 doesn't work.
- I still cannot believe this
newprint
example. This is an automatic fail. And the nerve of the author for even teaching this. - There's a bit on two-dimensional arrays that is not in the 2nd. ed. It's not particularly noteworthy and its "solution" is nothing that C programmers do.
- The horrendous
combine
function is here, in its original awfulness. - Chapter 8 only has the 2-D array stuff as a difference. Other than that, it's the same.
- Chapter 9 contains stuff on structures and pointers to pointers. There's a brief mention of unions. In the second edition, this is turned into 3 chapters: one on structs, one on unions, and one on pointers-to-pointers. The material in the first edition is a subset of it.
- And yes, it's as bafflingly bad as in the 2nd. ed. Programs are just as wrong.
- Chapter 10 is the same as chapter 12 in the second edition.
- Overall, the formatting in the first edition adheres to his coding guidelines. The second edition is much worse, so I suspect there was something up in how it was typeset.
- Oh, and the index sucks too. It doesn't contain useful
concepts—like
free
— but does contain an entry for "GIGO" (see above).