目录 ← 首页
CS61C

C Variables

Learning 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.h typedefs 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 false values are 0, NULL, and false.

C Basic Types

Just like in Java, all C variables are typed.

Why 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;


  • y stores a 16-bit unsigned integer. (See below regarding uint16_t)
  • y is initialized to a 16-bit unsigned representation of 38, i.e., the 16 bits 0000 0000 0010 0110.

sizeof

While types of variables can’t change, you can typecast values and define new variable types. This is discussed in the laundry list.

Sizes of Integer Types

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:

sizeof(long long)sizeof(long)sizeof(int)sizeof(short)\texttt{sizeof(long long)} \geq \texttt{sizeof(long)} \geq \texttt{sizeof(int)} \geq \texttt{sizeof(short)}

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.

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 NN-bit-wide datatype (say, because we want to represent 2N2^N non-integer things) might use int, then need to change types to work on another machine.

Variable declaration and initialization

Cautionary note: A lot of C has “undefined behavior.” It is totally possible for a C program to 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!3

Consider the following code. What is printed?

#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=22622

After editing comments and rerunning, I got different output a second time. What’s happening?

The 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 0
    • NULL, which is also defined as 0, but is commonly used for pointers. More later.
    • false, if stdbool.h is used
  • True values: Everything else.4

Footnotes

  1. See [StackOverflow](The array name a is the address of the first element in a; ) for differences between inttypes.h and stdint.h. For the purposes of this class, either is fine.

  2. More precisely, inttypes.h declares many typedef names of the form intN_t and uintN_t that designate two’s complement and unsigned integer types, respectively, of specific bitwidth N.

  3. “Heisenbugs” are bugs that seem random/hard to reproduce, and seem to disappear or change when debugging. By comparison, “Bohrbugs” are repeatable and reproducible.

  4. Python also has truthy and falsy values. See Stack Overflow.