1 of 30

Lab 1

61C Fall 2024

2 of 30

Compiling a C Program

  • gcc is used to compile C programs
  • gcc ex1.c test_ex1.c

  • Can specify the name of the executable file with the -o flag
    • gcc -o ex1 ex1.c test_ex1.c

ex1.c

test_ex1.c

gcc

a.out

3 of 30

Running a C Program

  • To run an executable located in the current directory, use ./<executable_name>
    • ./ex1
  • The dot refers to the current directory
  • If you want to run a file in a different directory, specify the path after the dot
    • ./path/to/file/ex1

4 of 30

Variable Types and Sizes

  • char = 1 byte (8 bits)
  • short = usually 2 bytes (16 bits)
  • int = usually 4 bytes (32 bits)
    • unsigned int
  • float = 4 bytes (32 bits)
  • double = 8 bytes (64 bits)
  • long = at least 4 bytes (32 bits), can be longer
  • long long = at least 8 bytes (64 bits), can be longer

Guarantee: sizeof(long long) >= sizeof(long) >= sizeof(int) >= sizeof(short)

To know for sure what size your variable is, use uintN_t or intN_t types.

5 of 30

Defining a Function

Specify return type, function name, and function parameters.

int add(int x, int y) { return x + y; }

void nothing() { return; }

6 of 30

Conditionals

if (condition) {� do this;�} else if (condition) {� do this;�} else {� do this;�}

If-else

Switch statements

switch (expression) {

case constant1: � do these;

break;� case constant2:

do these;

break;

default:

do these;�}

7 of 30

Loops

While loop

For loop

while (condition) {

do this;�}

for (int i = 0; i < 10; i++) {

do this;

}

8 of 30

Pointers

  • *
    • Type definition
      • e.g. int* x_ptr;
      • Add an * after a type makes the type a pointer type. In the example, we declare x_ptr variable as integer pointer type, and assign the address of variable x as its value.
      • You can also do int**, int***, int****, …
    • Dereference
      • e.g. *x_ptr
      • Add an * before a variable gets the value at address [variable]
  • &
    • Get the address of a variable (opposite of dereference)
      • &x

100

Address

Data

0xebafb32c

x_ptr

x

&x

int* x_ptr;

int x = 100;

x_ptr = &x;

9 of 30

Address

Data

0x61c0

19

0x61c4

0x61c0

0x61c8

14

Memory

x

&x

y

Assigning

int x = 19;

int* y = &x;

might produce something like:

10 of 30

Address

Data

0x61c0

19

0x61c4

0x61c0

0x61c8

19

Memory

y

Assigning

(int* y = &x;)

int z = *y;

might produce something like:

z

*y / x

&x

11 of 30

Address

Data

0x61c0

20

0x61c4

0x61c0

0x61c8

19

Memory

y

Assigning

(int* y = &x;)

int z = *y;

*y = 20;

might produce something like:

z

*y / x

&x

12 of 30

Address

Binding

Data

0x61c0

x

19

0x61c4

y

0x61c0

0x61c8

z

14

Name

Value

x

19

&x

0x61c0

y

0x61c0

*y

19

13 of 30

Address

Binding

Data

0x61c0

x

19

0x61c4

y

0x61c0

0x61c8

z

14

Name

Value

x

19

&x

0x61c0

y

0x61c0

*y

19

&x gets the address of the variable x

14 of 30

Address

Binding

Data

0x61c0

x

19

0x61c4

y

0x61c0

0x61c8

z

14

Name

Value

x

19

&x

0x61c0

y

0x61c0

*y

19

To create a pointer, we need to declare y to be a pointer type:

int* y = &x;

15 of 30

Address

Binding

Data

0x61c0

x

19

0x61c4

y

0x61c0

0x61c8

z

14

Name

Value

x

19

&x

0x61c0

y

0x61c0

*y

19

*y follows the pointer in y, and gets the data stored at that address

16 of 30

Pointers

0xebafb32c

What will this print?

17 of 30

Pointers

0xebafb32c

0xebafb32c

18 of 30

Pointers

0xebafb32c

0xebafb32c

What will this print?

19 of 30

Pointers

0xebafb32c

0xebafb32c

Another address, ex: 0xebafb320

20 of 30

Pointers

0xebafb32c

0xebafb32c

0xebafb320

What will this print?

21 of 30

Pointers

0xebafb32c

0xebafb32c

0xebafb320

22

22 of 30

Pointers

0xebafb32c

0xebafb32c

0xebafb320

22

What will this print?

23 of 30

Pointers

0xebafb32c

0xebafb32c

0xebafb320

22

22

24 of 30

Pointers

0xebafb32c

22

Address

Data

0xebafb330

0xebafb32c

&my_var

my_var_p

&my_var_p

my_var

*my_var_p

&x = address of x

*x = contents at x

25 of 30

Pointers to Structs

  • Pass a pointer of a struct to a function so that you can edit the contents
  • Access the struct contents by:
    • (*student).major
    • student->major

Arrow operator

26 of 30

Arrays

  • A block of memory: size is static
    • int arr[2];
    • int arr[] = {1, 2};
  • Accessing elements: array indexing
    • arr[1]
  • An array variable is a “pointer” to the first element.
    • You can use pointers to access arrays!
    • arr[0] is the same as *arr
    • Can use pointer arithmetic to move the pointer
      • Each operation automatically moves the size of one whole “type” that ptr points to
      • arr[1] is the same as *(arr + 1)
  • Arrays do not keep track of their own size

27 of 30

Strings

  • An array of chars representing individual characters
    • Ends in a null terminator ‘\0’
  • strlen(char* string)
    • returns the length of the string (num chars until the null terminator)
  • strcpy(char* dest, char* src)
    • copies the string stored in src to the location dest, until and including the null terminator

28 of 30

Structs

  • What do they allow us to do?
  • What is a structure tag?
  • What are the two ways to declare struct variables?
  • How do we access the members of a struct?

Structure Tag

Variable declarations

29 of 30

Structs

  • What do they allow us to do?
  • What is a structure tag?
  • What are the two ways to declare struct variables?
  • How do we access the members of a struct?

Dot operator

30 of 30

Structs

  • typedef
    • Lets you avoid rewriting struct every time you want to declare a new struct variable
    • Can no longer declare variables in the struct definition