Lecture 16: Types
Watch on YouTube →
Overview
Burton Ma compares C types with Java and Python, focusing on how C handles `const`, arrays, strings, and structs. He emphasizes practical hazards such as unchecked array indexes, `sizeof` returning pointer size for array parameters, and the need to reserve space for a string’s null terminator.
Key takeaways
- C does not perform array bounds checks: an invalid index can silently overwrite adjacent memory, cause undefined behavior, or create a buffer overrun vulnerability.
- `sizeof` reports an array’s byte size in its declaration scope, but an array parameter becomes a pointer, so `sizeof` there cannot recover the original element count.
- A C string requires one more byte than its visible character count because every string must end with `\0`; string functions can read past allocated memory if that terminator is missing.
- `strlen` scans characters until it finds `\0`, so calling it repeatedly inside a loop can repeatedly traverse the string instead of reusing a stored length.
- C structs provide named groups of fields but not Java-style methods or constructors; assigning a struct copies its field values into an independent object.
Chapters
- A C `const` variable cannot be assigned after declaration, unlike Java `final`, which can be assigned once later; initialize C constants such as pi when declaring them.
- Math functions such as `sin` and `cos` are declared in `math.h`, and programs using them may need the linker option `-lm`.
- `void` indicates no return value or an empty parameter list; a regular variable cannot have type `void`, while `void *` can point to any object.
- C arrays, like Java arrays, store a contiguous sequence of elements of one type, and their size cannot be changed after creation.
- An array declaration such as `int x[10]` specifies capacity, and array indexes start at zero with no negative-index convention.
- C does not check array bounds, so using an index outside the declared capacity can cause undefined behavior rather than a runtime exception.
- A local C array such as `int x[3]` is not automatically zero-initialized, unlike a Java numeric array.
- An initializer list such as `{1, 2, 3}` initializes the three elements, while `{1}` initializes only the first and leaves the others indeterminate.
- An initializer list can determine array capacity when the declaration omits it, but too many initializers produce a compiler warning that should be fixed.
- `sizeof x` for an array of three four-byte `int` values returns 12 bytes, not the element count of three.
- Dividing `sizeof x` by `sizeof x[0]` can count elements only while `x` is still an actual array in that scope.
- When an array is passed to a function, it decays to a pointer; `sizeof` on that parameter returns pointer size, which was eight bytes on Burton Ma’s machine, not the original array length.
- Writing to `x[3]` in an array with three elements is out of bounds and has undefined behavior, even if the program compiles and runs.
- Burton Ma demonstrates a GCC layout where writing the fourth value into one array overwrites the first value of a neighboring array.
- Such buffer overruns can corrupt unrelated data and create security vulnerabilities; detecting them may require tools beyond the compiler.
- C has no built-in string type: a string is a `char` array whose end is marked by the null character `\0`.
- The literal `"CISC 220"` contains seven visible characters but requires eight array elements, including the terminator.
- `strlen`, declared in `string.h`, reports seven for `"CISC 220"` because it excludes the null terminator; the array may have additional unused capacity.
- C does not concatenate strings with `+`; joining `"CISC"` and `"220"` requires copying characters manually or using a library function such as `strcat`.
- A destination for four characters plus three characters needs at least eight bytes: seven visible characters and one `\0` terminator.
- The manual example copies both parts into a `char` array and explicitly writes the terminator at index 7; repeatedly calling `strlen` also rescans the string each time.
- C standard string functions search memory for `\0`; without a terminator, they may read beyond the allocated array until encountering a zero byte.
- Allocating one byte with `malloc` and storing `'C'` leaves no room for a terminator, so `strlen` returning 1 is only a coincidence.
- A missing terminator can produce incorrect results or crashes, making it essential to allocate space for and write the final `\0`.
- A C `struct` groups related fields into a composite type; `struct point2` contains two `double` members, `x` and `y`.
- The type name includes the `struct` keyword, and members are accessed with dot notation such as `p.x` and `p.y`.
- Structs contain data but no methods or constructors; assigning one struct to another of the same type copies its fields, so later field changes remain independent.
Transcript excerpt
0:02 Okay, good afternoon everybody. So, we're going to continue from where we left off in the last class. Uh so, we're in the types notebook of the C part of the course. Uh we just finished talking about floating point numbers. There's nothing special about floating point numbers. They behave exactly the same in C as they do in Java. Um so, the next thing I want to tell you about is uh this keyword called const. Uh so, you can declare a variable to be const, uh which makes the variable unassignable. Uh so, remember in the last class I made an effort to distinguish between assignment versus initialization. Uh so, this says if you make a variable that's const, you can't assign to the variable. Uh and so, that means you probably almost certainly want to initialize the variable. Um basically, what that means is
0:49 you end up with a value that can never change, uh which is useful for some things, right? So, for example, if you're defining the value of pi, uh it probably makes sense to declare it const. This is almost but not exactly the same as final in Java. Uh so, in Java, uh final means you can only assign to the variable once. It doesn't mean you have to initialize it, though. Uh so, Oops, sorry. There's a little Java program that declares a final variable called X. It hasn't been initialized yet. Um and it hasn't been given a value yet. Uh final means you can give it a value exactly once. So, on the next line or somewhere later in the program, you can
1:36 write X equals 1, and that's fine. You've given X a value exactly once. Uh and this works just fine. So, if you compile it with the Java compiler,
This is the start of the transcript. Save this video free for the whole transcript, searchable and time-coded.
In this course
Related notes
Summary, takeaways, and chapters were generated by AI from the video's transcript and may contain errors. The video belongs to its creator, Burton Ma.