1Learning Outcomes¶
You are not expected to learn the many, many details of C off the bat. But you should know how to declare and initialize variables.
Declare and initialize basic variable types in C.
Use
stdint.htypedefs where possible, because widths of basic integer types are processor-dependent.Always remember that uninitialized variables contain garbage.
Remember that all values in C can be cast to booleans, and the only
falsevalues are0,NULL, andfalse.
🎥 Lecture Video
2C Basic Types¶
Just like in Java, all C variables are typed.
| Type | Description | Example |
|---|---|---|
int | Integer Numbers (including negatives) | 0, 78, -217, 0x7337 |
unsigned int | Unsigned Integers (i.e., non-negatives) | 0, 6, 35102 |
float | Floating point decimal | 0.0, 3.14159, 6.02e23 |
double | Equal or higher precision floating point | 0.0, 3.14159, 6.02e23 |
char | Single character | 'a', 'D', '\\n' |
short | Shorter int | -7 |
long | Longer int | 0, 78, -217, 301720971 |
long long | Even longer int | 3170519272109251 |
2.1Why are variables typed?¶
A variable’s type is fixed at compile-time and cannot change for the duration of the program. This actually helps the compiler determine how to translate the program to machine code designed for the computer’s architecture:
How many bytes does this variable take up in memory?
What operators can this variable support?
uint16_t y = 38;
ystores a 16-bit unsigned integer. (See below regardinguint16_t)yis initialized to a 16-bit unsigned representation of 38, i.e., the 16 bits0000 0000 0010 0110.
2.2sizeof¶
While types of variables can’t change, you can typecast values and define new variable types. This is discussed in the laundry list.
2.3Sizes of Integer Types¶
Show Answer
Only (A) is always true across processors. The C standard does not define the size of int; it only guarantees that it is at least 8 bits wide.
The C standard does not define the absolute size of all integer types! The standard only defines that char is 1 byte wide. All other types have relative size guarantees:
Remember, C was built for efficiency. Early on, they determined that the size of int was the size most efficient to read, write, and operate on two’s complement numbers. So a 32-bit machine would often have 4-byte integers (4 bytes = 32 bits) if the datapath was built for 32-bit values, and a 64-bit machine would have 8-byte integers (8 bytes = 64 bits), but not always.
Table 2:Integer types in C, Java and Python
| Language | size of integer (in bits) |
|---|---|
| Python | 32 bits (plain ints), infinite (long ints) |
| Java | 32 bits |
| C | Depends on computer; 16 or 32 or 64 |
To write a C program, then, one would really need to know the intricacies of hardware. But this loses the benefit of portability; code that assumes an -bit-wide datatype (say, because we want to represent non-integer things) might use int, then need to change types to work on another machine.
3Variable declaration and initialization¶
Cautionary note: A lot of C has “undefined behavior.” It is totally possible for a C program will run one way on one computer and some other way on another. It is even possible to run differently each time the program is executed on the same machine![2]
Consider the following code. What is printed?
1 2 3 4 5 6 7 8 9 10 11 12#include <stdio.h> int main(int argc, char *argv[]) { int32_t x = 0; int32_t y; printf("before: x=%d, y=%d\n", x, y); x++; y += x; printf(" after: x=%d, y=%d\n", x, y); return 0; }
I tried running this on the CS 61C machines and got the following output the first time, and different output after I inserted some comments:
before: x=0, y=22621
after: x=1, y=22622After editing comments and rerunning, I got different output a second time. What’s happening?
4The C bool type¶
The bool type is a built-in type as of C23. For earlier versions (e.g., C17), we need to #include <stdbool.h> for definitions of true and false.
Values in C are truthy—meaning, every value can be interpreted as true or false.
False values:
0, i.e., all bits of this value are 0NULL, which is also defined as0, but is commonly used for pointers. More later.false, ifstdbool.his used
True values: Everything else.[3]
Show Answer
It prints meaning of life (plus a newline) because regardless of the integer width used, the constant 42 will have a non-zero bit representation. All non-zero bit representations are true.
More precisely,
inttypes.hdeclares manytypedefnames of the formintN_tanduintN_tthat designate two’s complement and unsigned integer types, respectively, of specific bitwidthN.“Heisenbugs” are bugs that seem random/hard to reproduce, and seem to disappear or change when debugging. By comparison, “Borhbugs” are repeatable and reproducible.
Python also has truthy and falsy values. See Stack Overflow.