Even more C#

Relevant Reading

This lecture will cover contents from Chapter 2 and Chapter 3 of the book.

1. Addresses and pointers#

  • In Java, you can manipulate the value of a variable via the program but not directly in memory (inside the JVM).

  • In C, you can retrieve the address of the location in memory where the variable is stored.

  • The operator & (reference of) represents the memory address of a variable.

Hands-on: Pointer
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create pointer-1.cwith the source code below.

  • %p is an output conversion syntax (similar to Java specifiers) for displaying memory address in hex format. See Other Output Conversions for more details.

  • Compile and run pointer-1.c

ls
gcc -o pointer-1 pointer-1.c
./pointer-1
Compile and run pointer-1.c
Pointer Definition
  • Pointer is a variable that points to a memory location (contains a memory location).

    • We call them pointer variables.

  • A pointer is denoted by a * character.

  • The type of pointer must be the same as that of the value being stored in the memory location (that the pointer points to).

  • If a pointer points to a memory location, how do we get these locations?

    • An & character in front of a variable (includes pointer variables) denotes that variable’s address location.

Hands-on: Pointer and Variable’s Addresses
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create pointer-2.cwith the source code below.

  • Since p_i is a pointer variable, p_i contains a memory address (hence %p).

  • Then, *p_i will point to the value in the memory address contained in p_i.

    • This is referred to as de-referencing.

    • This is also why the type of a pointer variable must match the type of data stored in the memory address the pointer variable contains.

  • Compile and run pointer-2.c

Compile and run pointer-2.c
Pass by Value and Pass by Reference
  • Parameters are passed to functions.

  • Parameters can be value variables or pointer variables.

  • What is the difference?

Hands-on: Pass by value
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create pointer-3.cwith the source code below.

  • Compile and run pointer-3.c

Compile and run pointer-3.c
Hands-on: Pass by reference
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create pointer-4.cwith the source code below.

  • Compile and run pointer-4.c

Compile and run pointer-4.c
  • In Java, do you pass by value or pass by reference?

Answer
  • Primitives are passed by value.

  • Objects are passed by reference.

2. Pointers and memory allocation#

  • How does C request dynamic memory when you don’t know at compile-time exactly what you will need?

  • How does C allocate memory?

    • Automatic: compile arranges for memory to be allocated and initialized for local variables when it is in scope.

    • Static: memory for static variables are allocated once when program starts.

    • Dynamic: memory is allocated on the fly as needed.

Dynamic memory allocation
  • Unlike Java, you have to do everything!

    • Ask for memory.

    • Return memory when you are done (garbage collection!).

  • C function: malloc

    • void *malloc(size_t size);

    • The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().

  • C function: free

    • void free(void *ptr);

    • The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.

Void pointer
  • When malloc allocates memory, it returns a sequence of bytes, with no predefined types.

  • A pointer that points to this sequence of bytes (the address of the starting byte), is called a void pointer.

  • A void pointer will then be typecast to an appropriate type.

Hands-on: malloc and type cast
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create malloc-1.cwith the source code below.

  • What points to where:

    • void *p = malloc(4);: allocate 4 contiguous bytes. The address of the first byte is returned and assign to pointer variable p. p has no type, so it is a void pointer.

    • int *ip = (int *)p;: The address value pointed to by p is assigned to pointer variable ip. The bytes pointed to be p are now casted to type int.

  • Compile and run malloc-1.c

Compile and run malloc-1.c
Hands-on: malloc and type cast with calculation
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create malloc-2.cwith the source code below.

  • Only ask for exactly what you need!

  • Compile and run malloc-2.c

Compile and run malloc-2.c
Hands-on: Safety
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create malloc-3.cwith the source code below.

  • Return and free memory after you are done!

  • Compile and run malloc-3.c

Compile and run malloc-3.c
Dynamic memory allocation
  • Critical to support complex data structures that grow as the program executes.

  • In Java, custom classes such as ArrayList and Vector provide such support.

  • In C, you have to do it manually: How?

  • Let’s start with a simpler problem:

    • How can we dynamically allocate memory to an array whose size is not known until during run time?

7. Array in C#

  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create array-1.cwith the source code below.

  • What is the distance between addresses? Why?

  • Compile and run array-1.c

Compile and run array-1.c
Exercise
  • Create a copy of array-1.c called array-2.c.

  • Change the type of numbers to double.

  • What is the address step now?

Answer
Compile and run array-2.c
An array variable
  • … is in fact pointing to an address containing a value.

  • … without the bracket notation and an index points to the corresponding address of the value at the index.

  • … is quite similar to a pointer!

Hands-on: Array as pointer (or vice versa …)
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create array-3.cwith the source code below.

  • Compile and run array-3.c

Compile and run array-3.c

8. Command line arguments.#

  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create array-4.cwith the source code below.

  • In C, the command line arguments include the program’s name. The actual arguments start at index position 1 (not 0 like Java).

  • Compile and run array-4.c

Compile and run array-4.c

9. String#

  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create string-1.cwith the source code below.

  • Compile and run string-1.c

Compile and run string-1.c
  • In C, string is considered an array of characters.

  • How many characters were printed out on the second line in the terminal?

  • Hint: Can you see all of them?

Answer

24

Hands-on: Array of strings
  • Inside the terminal, make sure that you are still inside intro-c, then use nano to create string-2.cwith the source code below.

  • Compile and run string-2.c

Compile and run string-2.c

10. Object in C#

  • C has no classes or objects.

  • Instead, it has struct type (think ancestor of objects) .

Hands-on: Struct in C
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create struct-1.cwith the source code below.

  • Compile and run struct-1.c

Compile and run struct-1.c
Challenge
  • Modify struct-1.c so that it prints out the address of origin variable.

  • What do you learn from the printed out addresses?

Answer

Insert printf("The address of the origin is: %p\n", &origin); between the existing printf calls.

Hands-on: Struct of structs in C
  • Inside the terminal, make suse that you are still inside intro-c, then use nano to create struct-2.cwith the source code below.

  • Compile and run struct-2.c

Compile and run struct-2.c

11. Function in C#

  • Almost the same as methods in Java, except for one small difference.

  • They need to either be declared, or must be defined prior to being called (relative to written code position).

Hands-on: Functions in C - definition and declaration
  • Create three C files, function-1.c, function-2.c, and function-3.c, with the source codes below:

  • Compile and run these files.

Compile and run function-1.c, function-2.c, function-3.c