Try to do each one without looking at the solution. If you’re stumped, look at the solution and read the notes that I put in there as well. I try to explain why I solved it that way.

Table of contents, by lecture/lab


Discovering the sizes of things with sizeof() (Lab 2)

sizeof() is not how you get the length of an array. You cannot get the length of an array in C because that information is unavailable at runtime.

There are two kinds of numerical types in C: integer types and floating-point types.

There are also signed integers (the default) or unsigned integers (which cannot represent negative numbers.) Java doesn’t have these unsigned integers!

Did you know? sizeof() is not how you get the length of an array. You cannot get the length of an array in C because that information is unavailable at runtime.

Unlike Java, the sizes of the integer types in C are not fixed. They depend on the platform: what CPU and operating system you’re using. There are some common sizes for these types that you are statistically far more likely to encounter, but they are not always that size.

You can find out the size of a type using the sizeof operator. Although it may look like a function, this is NOT a function that executes at runtime. It operates at compile time and gives you a constant value saying how many bytes something takes up.

The sizes of the integer types in C follow these (in)equalities:

sizeof(char) == 1
sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)

char is an integer type in C. You can use a char whenever you need a one-byte value or an array of one-byte values. (ASCII/UTF-8 characters are a special case of one-byte value.)

Now for practice

Make a new file called sizeof.c. Inside, include stdio.h as usual. Inside main, put this code:

The (int) in there is to cast the result of sizeof to an int. Otherwise, you’ll get annoying warnings.

	int x = 10;
	printf("sizeof(x) = %d\n", (int)sizeof(x));
	printf("sizeof(int) = %d\n", (int)sizeof(int));

Compile it like gcc -Wall -Werror --std=c99 -o sizeof sizeof.c

Run it like ./sizeof. What does it print? Is that what you expected it to print?

Did you really create, compile, and run that program, or are you just trying to look at the answer because it seems “too easy” for you? ;) Cmon, go do it and see what it prints.

It prints:

sizeof(x) = 4
sizeof(int) = 4

If you were expecting it to print the sizes of the values in bits, that’s understandable, but no: everything in memory is measured in multiples of bytes, so the byte size is a much more useful thing to know.

Well strictly speaking everything in memory is measured in multiples of the “smallest addressable unit of memory,” which is “a byte” on almost every computer around today. But there are computers which are word-addressable, in which case sizeof(int) may be 1!

Now extend it. Print the sizes of the following types:

Make notes of what these print. Things to ask yourself/notice:

I’m not gonna tell you the answers here. Go do it!

Array variables are really weird

Okay, now to blow your mind some. Add this code to the beginning of main:

	char a[10];
	int b[10];
	int* c = b;

Then add some more lines to print out:

What the hell is going on?

Array variables are the ones declared with brackets (here, a and b are array variables). C treats them very strangely. They’re kind of pointers but kind of not.

When you use sizeof() on an array variable, it tells you how many bytes it takes up. It does NOT tell you the length, at least not directly. (Compare sizeof(a) and sizeof(b). They’re the same length, but they’re different numbers of bytes, because their items are different sizes!)

But when you use sizeof() on a pointer type like c, it gives you the size of the pointer. It never gives you the length of the array that the pointer points to.

The size of an array variable is only available:

VLAs work a little differently. We’ll get to those.

32-bit machines

Thoth is a 64-bit machine. But you can compile a 32-bit executable by using the -m32 flag to gcc, like so:

gcc -Wall -Werror --std=c99 -m32 -o sizeof sizeof.c

Now run ./sizeof. Which numbers changed? Why do you think that is?

Seems like many (but not all!) things that are 8 bytes (64 bits) on x86-64 are 4 bytes (32 bits) on x86-32. A 32-bit CPU has 32-bit registers and can only perform 32-bit loads and stores, so that seems reasonable enough.

Notice also that pointers are 4 bytes instead of 8. Generally, 32-bit machines can only use addresses that are 32 bits, and can only access 232 Bytes of memory, which is 4 GiB. This is the main reason we moved to 64-bit architectures - so we could access more than 4 gigabytes of memory. Having bigger integers is just a bonus!

Conclusion: Things to remember