Week 7 Code Examples
// COMP1511 Week 5 Lecture 2
// variables/data are passed into functions by value
// a copy of the value gets passed into the function
// so changes made in the function are on the local copy
#include <stdio.h>
void update(int x, int y);
void swap(int x, int y);
int main(void) {
int x = 2;
int y = 5;
printf("%d %d\n", x, y);
update(x,y);
printf("%d %d\n", x, y);
swap(x, y);
printf("%d %d\n", x, y);
return 0;
}
// This function will only modify the local copy of x and y
void update(int x, int y) {
x = x + 1;
y = y - 1;
}
// This function will only modify the local copy of x and y
void swap(int x, int y) {
int tmp = x;
x = y;
y = tmp;
}
// COMP1511 Week 5 Lecture 2
// variables/data are passed into functions by value
// a copy of the value gets passed into the function
// Here we pass in the addresses of the variables
// so we can go directly to their address and modify
// them from within the function
#include <stdio.h>
void update(int *x, int *y);
// TO DO FIX SWAP
void swap(int *x, int *y);
int main(void) {
int x = 2;
int y = 5;
printf("%d %d\n", x, y);
// Pass in the addresses of x and y
// So update can use the addresses to
// go modify x and y
update(&x, &y);
printf("%d %d\n", x, y);
//TODO FIX THIS
swap(&x, &y);
printf("%d %d\n", x, y);
return 0;
}
// This function uses pointers.
// We can dereference x and y and modify the data
// at the given addresses
void update(int *x, int *y) {
*x = *x + 1;
*y = *y - 1;
}
// This function will only modify the local copy of x and y
// TODO FIX
void swap(int *x, int *y) {
int tmp = *x;
*x = *y;
*y = tmp;
}
// COMP1511 Week 5 Lecture 2
// variables/data are passed into functions by value
// a copy of the value gets passed into the function
#include <stdio.h>
struct point {
int x;
int y;
};
void update(struct point p);
int main(void) {
struct point p;
p.x = 10;
p.y = 9;
update(p);
printf("(%d,%d)\n", p.x, p.y);
return 0;
}
// This function will only modify the local copy of p
void update(struct point p) {
p.x = p.x + 1;
p.y = p.y + 1;
}
// COMP1511 Week 5 Lecture 2
// variables/data are passed into functions by value
// a copy of the value gets passed into the function
// TO DO MODIFY THIS TO USE POINTERS
#include <stdio.h>
struct point {
int x;
int y;
};
void update(struct point *my_point);
struct point update2(struct point p);
int main(void) {
struct point p;
p.x = 10;
p.y = 9;
update(&p);
printf("(%d,%d)\n", p.x, p.y);
p = update2(p);
printf("(%d,%d)\n", p.x, p.y);
return 0;
}
// This function will only modify the local copy of p
// Modify this version to use pointers.
void update(struct point *my_point) {
my_point->x = my_point->x + 1;
my_point->y = my_point->y + 1;
}
struct point update2(struct point p) {
p.x++;
p.y++;
return p;
}
// COMP1511 Week 7
// Recap Exercise.
// Try to read and work out what it will print
// before running the code.
#include <stdio.h>
int main(void) {
int x = 2;
int y = 5;
int *ptr1 = &y;
int *ptr2 = &x;
int z = *ptr1 + *ptr2;
*ptr2 = z * 2;
printf("%d %d %d %d %d\n", x, y, z, *ptr1, *ptr2);
ptr1 = ptr2;
printf("%d %d %d %d %d\n", x, y, z, *ptr1, *ptr2);
return 0;
}
// COMP1511 Week 7
// A demonstration to show how arrays are stored in memory
#include <stdio.h>
#define MAX_LEN 5
void print_array(int *nums, int length);
void print_array2(int nums[], int length);
int main(void) {
int array[MAX_LEN] = {9, 2, 3};
printf("array address: %p\n", array);
int i = 0;
while (i < MAX_LEN) {
printf("Address of array[%d] = %p\n", i, &array[i]);
i++;
}
print_array(array, MAX_LEN);
print_array2(array, MAX_LEN);
return 0;
}
void print_array(int *nums, int length) {
printf("\naddress of array in print_array: %p\n", nums);
for (int i = 0; i < length; i++) {
printf("%d\n", nums[i]);
}
}
void print_array2(int nums[], int length) {
printf("\naddress of array in print_array: %p\n", nums);
for (int i = 0; i < length; i++) {
printf("%d\n", nums[i]);
}
}
// COMP1511 Week 7
#include <stdio.h>
#define MAX_LEN 5
void print_array(int nums[], int length);
void increment_all(int nums[], int length);
int main(void) {
int nums[MAX_LEN] = {1, 2, 3, 4, 5};
printf("Before increment all: \n");
print_array(nums, MAX_LEN);
increment_all(nums, MAX_LEN);
printf("After increment all: \n");
print_array(nums, MAX_LEN);
return 0;
}
void print_array(int nums[], int length) {
int i = 0;
while (i < length) {
printf("%d ", nums[i]);
i++;
}
printf("\n");
}
void increment_all(int nums[], int length) {
for (int i = 0; i < length; i++) {
nums[i] = nums[i] + 1;
}
}
// COMP1511 Week 7
#include <stdio.h>
int main(void) {
char s[] = "Pointers!!!";
char *sp = &s[1];
printf("%c\n", *sp);
printf("%c\n", sp[0]);
printf("%c\n", sp[1]);
printf("%s\n", sp);
sp = &s[8];
printf("%s\n", sp);
//We can't move where s points.
//s = &s[1];
return 0;
}
// Week 7 Lecture 1
// An example of returning an address of a local variable.
// Do NOT do this
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
int *create_array(void);
void print_array(int nums[], int size);
int main(void) {
int *data = create_array();
print_array(data, MAX);
return 0;
}
// returns a pointer to a malloced array
int *create_array(void) {
int data[MAX];
for (int i = 0; i < MAX; i++) {
data[i] = i*10;
}
return data;
}
void print_array(int nums[], int size) {
for (int i = 0; i < size; i++) {
printf("%d\n", nums[i]);
}
}
// Week 7 Lecture 1
// An example of returning an address of a local variable.
// Do NOT do this
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
int *create_array(void);
void print_array(int nums[], int size);
int main(void) {
int *data = create_array();
print_array(data, MAX);
free(data);
return 0;
}
// returns a pointer to a malloced array
int *create_array(void) {
int *data = malloc(sizeof(int) * MAX);
if (data == NULL) {
printf("Out of memory\n");
exit(1);
}
for (int i = 0; i < MAX; i++) {
data[i] = i*10;
}
return data;
}
void print_array(int nums[], int size) {
for (int i = 0; i < size; i++) {
printf("%d\n", nums[i]);
}
}
// Week 7 Lecture 1
// An example of creating an array of a size
// determined at run time using malloc
#include <stdio.h>
#include <stdlib.h>
int *create_array(int num_elements);
void print_array(int nums[], int size);
int main(void) {
int num_elements;
printf("How many elements? ");
scanf("%d", &num_elements);
int *data = create_array(num_elements);
if (data != NULL) {
print_array(data, num_elements);
free(data);
}
return 0;
}
// returns a pointer to a malloced array
int *create_array(int num_elements) {
int *data = malloc(num_elements *sizeof(int));
if (data == NULL) {
printf("Out of memory\n");
return NULL;
}
// You can still use array notation!!!!
for (int i = 0; i < num_elements; i++) {
data[i] = i*10;
}
return data;
}
void print_array(int nums[], int size) {
for (int i = 0; i < size; i++) {
printf("%d\n", nums[i]);
}
}
// Week 7 Lecture 2
// An example of creating and returning a malloced struct
// from a function
#include <stdio.h>
#include <stdlib.h>
#define MAX_LEN 128
struct coordinate {
int x;
int y;
};
// Write a function to return a pointer
// to a coordinate struct with given x and y
struct coordinate *create_coordinate(int x, int y);
// prints out the coordinate in the format (x, y)
void print_coordinate(struct coordinate *p);
int main(void) {
// Call the first function to create a coordinate with
// with coordinates (10, -1)
struct coordinate *my_coord = create_coordinate(10, -1);
// Call the second function to print the coordinate
print_coordinate(my_coord);
struct coordinate *my_coord2 = create_coordinate(9, 1000);
// Call the second function to print the coordinate
print_coordinate(my_coord2);
// Anything else we need to do?
free(my_coord);
free(my_coord2);
return 0;
}
// Write a function to return a pointer
// to a coordinate struct with given x and y
struct coordinate *create_coordinate(int x, int y) {
struct coordinate *new_coord = malloc(sizeof(struct coordinate));
if (new_coord == NULL) {
printf("Out of memory\n");
exit(1);
}
new_coord->x = x;
new_coord->y = y;
return new_coord;
}
// prints out the coordinate in the format (x, y)
void print_coordinate(struct coordinate *p) {
printf("(%d, %d)\n", p->x, p->y);
}
// Week 7 Lecture 2
// An example of creating and returning a malloced struct
// from a function
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 128
struct person {
char name[MAX_LEN];
int age;
};
// return a pointer to a person struct with name and age
struct person *create_person(char *name, int age);
void print_person(struct person the_person);
int main(void) {
struct person *my_person = create_person("Tina Arena", 58);
print_person(*my_person);
free(my_person);
return 0;
}
// return a pointer to a person struct with name and age
struct person *create_person(char *name, int age) {
struct person *new_person = malloc(sizeof(struct person));
if (new_person == NULL) {
return NULL;
}
strcpy(new_person->name, name);
new_person->age = age;
return new_person;
}
void print_person(struct person the_person) {
printf("%s %d\n", the_person.name, the_person.age);
}
// Week 7 Lecture 1
// An example of creating a memory leak
// on purpose
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i = 0;
while(1) {
printf("%d\n", i);
int *data = malloc(1000000 *sizeof(int));
if (data == NULL) {
printf("Out of memory\n");
return 0;
}
i++;
free(data);
}
return 0;
}
#include <stdio.h>
int *f(void);
int main(void) {
int *p = f();
if (p != NULL) {
printf("%d\n", *p);
}
return 0;
}
int *f(void) {
return NULL;
}
// An example of creating an array of a size
// determined at run time using malloc
// then resized using realloc
// This is more of an advanced example
#include <stdio.h>
#include <stdlib.h>
int *create_array(int num_elements);
void print_array(int nums[], int size);
int main(void) {
int num_elements;
printf("How many elements? ");
scanf("%d", &num_elements);
int *data = create_array(num_elements);
if (data == NULL) {
return 1;
}
printf("Original Array: ");
print_array(data, num_elements);
// Decide we need a bigger array!
// Common to double the size if you don't have an exact new size
// Usually making the array just 1 element larger is not a great idea
// as you may then ending up reallocing many times. But this is
// just a simple example
int new_num_elements = num_elements + 1;
// In case realloc returns NULL we do not want to lose our
// original address of our data
int *tmp_data = realloc(data, sizeof(int) *new_num_elements);
if (tmp_data == NULL) {
//If tmp_data is NULL, we will still have the original array in data
printf("Can't make it bigger\n");
} else {
//If tmp_data was not NULL now that is the address of our new
//bigger chunk of data
data = tmp_data;
}
// Giving values to the extra data in the array so we can print it
// out and see that it is indeed bigger now.
data[new_num_elements - 1] = 99;
printf("Realloced Array: ");
print_array(data, new_num_elements);
//print_array(data, num_elements);
free(data);
return 0;
}
// returns a pointer to a malloced array
// or NULL if the malloc failed
int *create_array(int num_elements) {
int *data = malloc(num_elements *sizeof(int));
if (data == NULL) {
printf("Out of memory\n");
return NULL;
}
// You can still use array notation!!!!
for (int i = 0; i < num_elements; i++) {
data[i] = i*10;
}
return data;
}
void print_array(int nums[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", nums[i]);
}
printf("\n");
}
// COMP1511 Week 7 Lecture 1
// sizeof can tell us how many bytes our different types or variables
// are stored in
// We need to print it with %lu instead of %d
#include <stdio.h>
struct point{
int x;
int y;
int z;
};
int main(void) {
int x = 1;
printf("Size of x: %lu bytes\n", sizeof x);
printf("Size of an int: %lu bytes\n", sizeof(int));
printf("Size of char: %lu bytes\n", sizeof(char));
printf("Size of double: %lu bytes\n", sizeof(double));
printf("Size of 10 ints: %lu bytes\n", 10 * sizeof(int));
printf("Size of struct point: %lu bytes\n", sizeof(struct point));
printf("Size of a pointer: %lu bytes\n", sizeof(int *));
return 0;
}
// Week 7 Lecture 1
// Demonstrating multiple file programs
// Note that this .c file has a matching .h file, array_utilities.h
// It #includes this file.
// Note we use "" instead of <> for our own include files.
#include <stdio.h>
#include "array_utilities.h"
// Print every integer in the given array
void print_data(int size, int data[]) {
for (int i = 0; i < size; i++) {
printf("%d ", data[i]);
}
printf("\n");
}
// Print every odd integer in the given array
void print_odd_data(int size, int data[]) {
for (int i = 0; i < size; i++) {
if(data[i]%2 != 0) {
printf("%d ", data[i]);
}
}
printf("\n");
}
// Given a size, this function reads in enough integers
// to fill the given array.
// This function does not check for invalid input
void read_data(int size, int data[]) {
for (int i = 0; i < size; i++) {
scanf("%d", &data[i]);
}
}
// returns the maximum in a given array of ints
int find_maximum(int size, int data[]) {
int max = data[0];
for (int i = 1; i < size; i++) {
if (data[i] > max) {
max = data[i];
}
}
return max;
}
// This is the header file for our array_utilities module
// The header file can contain:
// - #defines
// - structs
// - enums
// - function prototypes and any comments
// Print every integer in the given array
void print_data(int size, int data[]);
// Print every odd integer in the given array
void print_odd_data(int size, int data[]);
// Given a size, this function reads in enough integers
// to fill the given array.
// This function does not check for invalid input
void read_data(int size, int data[]);
// returns the maximum in a given array of ints
int find_maximum(int size, int data[]);
// Week 7 Lecture example
// Every program needs exactly one main function
// This is where we drive the program from
// and where we make calls to our modules. We
// need to inclide the header file for each
// module that we want to use functions from.
#include <stdio.h>
// We need to include our header and use "" not <>
#include "array_utilities.h"
#define MAX_SIZE 3
int main(void) {
int numbers[MAX_SIZE] = {4, 6, 1};
if (find_maximum(MAX_SIZE, numbers) == 6) {
printf("Yay\n");
} else {
printf("Uhoh\n");
}
return 0;
}
// Week 7 Lecture example
// Every program needs exactly one main function
// This is where we drive the program from
// and where we make calls to our modules. We
// need to inclide the header file for each
// module that we want to use functions from.
// To compile the whole program:
// dcc -o program program.c array_utilities.c
// To run
// ./program
#include <stdio.h>
// We need to include our header and use "" not <>
#include "array_utilities.h"
#define MAX_SIZE 5
int main(void) {
int numbers[MAX_SIZE];
printf("Enter %d ints: ", MAX_SIZE);
read_data(MAX_SIZE, numbers);
print_data(MAX_SIZE, numbers);
int max = find_maximum(MAX_SIZE, numbers);
printf("The max is %d\n", max);
return 0;
}
// Week 7 Wednesday Lecture
// Create a list with nodes by adding nodes with data 0..9 to the beginning
// of an empty list
// Use a functions to create nodes
// Use a loop and a function to print nodes
// Test the print function with an empty list
// We will leave the function to free nodes until later
// For now we will have a memory leak in this program
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *create_node(int data, struct node *next);
void print_list(struct node *head);
int main(void) {
// Declare and initialise our list
// Right now this is an empty list but we will add nodes to it
struct node *head = NULL;
print_list(head);
// Temporary variable to hold new nodes
struct node *new_node = NULL;
//create a node with data value i using function
//add node to beginning of the list
for (int i = 0; i < 10; i++) {
new_node = create_node(i, head);
head = new_node;
}
// Use function to print list
print_list(head);
// Create an empty list to test print function
// We will learn how to free our list later
// For now we have memory leaks
return 0;
}
struct node *create_node(int data, struct node *next) {
struct node *new_node = malloc(sizeof(struct node));
if (new_node == NULL) {
return NULL;
}
new_node->data = data;
new_node->next = next;
return new_node;
}
void print_list(struct node *head) {
struct node *curr = head;
printf("list:\n");
while (curr != NULL) {
printf("%d ", curr->data);
curr = curr->next;
}
printf("\n");
}
// Week 7 Wednesday Lecture
// Create a list with 3 nodes
// Print the the contents of the first 3 nodes
// Free the nodes at the end
// This is repetitive
// We need to have functions to create nodes
// We need a less manual way to print the list
// We need a less manual way to free nodes
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
int main(void) {
// Create list
struct node *head = NULL;
// Print first 3 nodes in list
struct node *new_node = malloc(sizeof(struct node));
new_node->data = 9;
new_node->next = head;
head = new_node;
new_node = malloc(sizeof(struct node));
new_node->data = 2;
new_node->next = head;
head = new_node;
new_node = malloc(sizeof(struct node));
new_node->data = 7;
new_node->next = head;
head = new_node;
printf("%d ", head->data);
printf("%d ", head->next->data);
printf("%d ", head->next->next->data);
// There were only 3 nodes! This causes an error
//printf("%d ", head->next->next->next->data);
// Free nodes in list - we will learn this later
// For now we will leave our memory leaks
return 0;
}