9 CPS393 DataStructuresC
9 CPS393 DataStructuresC
Structured Data in C
2D arrays (static VS dynamic)
Arrays of strings
Structs, Linked Lists
#include <stdio.h>
int main()
{
int nums[100]; An array of 100 integers
return 0;
}
2D Static Arrays
#include <stdio.h>
int main()
{
int nums[10][10]; A 2D array, 10 by 10
return 0;
}
ND Static Arrays
#include <stdio.h>
int main()
{
int nums[5][5][5][5][5];
return 0;
}
#include <stdio.h>
int main()
{
int nums[3][2] = {{1, 2}, {3, 4}, {5, 6}};
return 0;
} Row 1 Row 2 Row 3
3 rows 2 columns
1 2 3 4 5 6 Memory
1 2 3 4 5 6 Memory
1 2 3 4 5 6 Memory
nums == &nums[0][0]
#include <stdio.h>
int main()
{
int matrix[2][2]; 2 rows, 2 columns
Row index Column index
matrix[0][0] = 17; /* row 0, col 0 */
matrix[0][1] = -3; /* row 0, col 1 */
matrix[1][0] = 0; /* row 1, col 0 */
matrix[1][1] = 57; /* row 1, col 1 */
return 0;
}
#include <stdio.h>
int main()
{
int matrix[2][2];
scanf( , &matrix[0][0]);
scanf( , &matrix[0][1]);
scanf( , &matrix[1][0]);
Just like 1D arrays!
scanf( , &matrix[1][1]);
return 0;
}
#include <stdio.h>
int main()
{
int matrix[][] = {{1,2,3},{4,5,6},{7,8,9}};
int row, col;
for (row = 0; row < 3; row++) {
for (col = 0; col < 3; col++) {
printf( , matrix[row][col]);
}
printf( \ );
}
return 0;
}
2D Static Arrays as Arguments
1 2 3 4 5 6 Memory
#include <stdio.h>
int main()
{
int nums[3][2] = {{1, 2}, {3, 4}, {5, 6}};
printf( , nums[1][1]);
return 0;
}
1 2 3 4 5 6 Memory
#include <stdio.h>
int main()
{
int nums[3][2] = {{1, 2}, {3, 4}, {5, 6}};
printf( , nums[1][1]);
return 0;
}
one row ends and another begins. 2D indexing would not be possible.
1 2 3 4 5 6 Memory
void addMatrix(int a[][N], int b[][N], int c[][N])
{
int row, col;
for (row = 0; row < M; row++)
for (col = 0; col < N; col++)
c[row][col] = a[row][col] + b[row][col];
}
arr
How can we
use calloc to
achieve this?
int i, nrows = 3, ncols = 4;
int **nums; /* Double pointer! A pointer to an array of pointers */
/* Allocate the array of pointers */
nums = (int**) calloc(nrows, sizeof(int*));
nums[2][2]
2D Array Allocation: ENG
1 2 3 4 5 6 Memory
1 2 3 4 5 6 Memory
nums[X*(num_cols) + Y];
Linear index of 2D array
2 columns
3 rows
first row second row third row
Engineering method:
Easier to set up, harder to use once set up.
Cost: Calculate linear index. One multiplication,
one addition. Single calloc call.
Zuck AND Iron Man
int R = 3, C = 3;
ENG int *arr = (int*) calloc(R*C, sizeof(int));
CS int **mat = (int**) calloc(R, sizeof(int*));
mat[0] = arr;
for (int i = 1; i < R; i++)
mat[i] = mat[i-1] + C;
Two 1D arrays:
First to hold all elements in the ENG style.
Second to enable 2D indexing in the CS style
integer
→ 4 bytes
Printing this pointer as %d gives a compile warning.
© Alex Ufkes, 2022 int is 4 bytes, int* is 8 bytes. We print the lower 4 bytes. 47
int R = 3, C = 3;
int *arr = (int*) calloc(R*C, sizeof(int));
int **mat = (int**) calloc(R, sizeof(int*));
mat[0] = arr; Address
of the
first element
first in the position .
Memory
Memory
#include <stdio.h>
int main()
{
char months[12][10];
return 0;
}
Maximum length
Number of strings
of each string
Array of Strings
char months[12][10] =
{ , , ,
, , ,
, , ,
, , };
Value of months[7][3]?
Value of months[4][3]?
Value of months[2][8]?
The memory is ours, but we
Value of months[9]?
Address of the first character
of October - &months[9][0]
printf( , months[9]);
Console
January
February
March char months[12][10] =
{ , , ,
April , , ,
May , , ,
June , , };
July
August
September for (i = 0; i < 12; i++)
October printf( \ , months[i]);
November
December
Structs
struct ball
{
char style[10];
double radius;
double weight;
};
#include <stdio.h>
#include <math.h>
struct ball
{ Structure definitions:
char style[10]; Typically placed between
double radius; preprocessor directives
double weight; and function prototypes.
};
int main()
{
return 0;
}
struct ball
{
char style[10];
double radius;
double weight;
};
int main()
{
struct ball b1, b2, b3, b[50]; Or as an array
Declare individually
}
struct ball
{
char style[10];
double radius;
double weight;
};
Use the dot operator to access a
int main() individual variables.
{
struct ball b1;
b1.radius = 4.6;
b1.weight = 22.1;
strcpy(b1.style, );
} ↓
destination element
the first
of
address
struct ball
{
char style[10];
double radius;
double weight;
};
int main()
{
struct ball b[50];
int i;
for (i = 0; i < 50; i++) {
Initialize radius
b[i].radius = 0.0;
b[i].weight = 0.0; and weight to 0.0
}
}
struct1 = struct2;
Assigns one struct to another
Assuming the same structure type
#include <stdio.h>
typedef int integer;
alias for type int
int main()
{
integer x, y, z;
x = 1; integer can now be used as a type!
y = 2; same as int, except for the
z = x + y; name.
}
Common for Structures
int main()
{
basketball b1 = { , 3.4, 6.8};
return 0;
}
typedef struct ball
{
char style[10];
double radius;
double weight;
} basketball;
This is DIFFERENT from arrays, which are NOT copied. Only the
base address of the array is copied, not the elements.
typedef struct ball
{ struct ball is defined and
char style[10];
given an alias before the
double radius;
double weight;
function printElements
} basketball;
void printElements(basketball b)
{
printf( \ , b.style);
printf( lf\ , b.radius);
printf( lf\ , b.weight);
}
typedef struct ball void printElements(basketball b)
{ {
char style[10]; printf( \ , b.style);
double radius; printf( lf\ , b.radius);
double weight; printf( lf\ , b.weight);
} basketball; }
b1 and its member
int main() values are copied into b
{
basketball b1 = { , 11.4, 212.8};
printElements(b1);
return 0;
}
Write a user-defined function that does the following:
Takes in two basketball structs as arguments and
compares the radius and the weight. Returns 1 if they
are the same, and 0 if they are different.
Two basketball structs as input arguments
int main()
{
basketball b1 = { , 11.4, 212.8};
basketball b2 = { , 11.4, 212.8};
if (comp(b1, b2))
printf( \ );
else
printf( \ );
return 0;
}
Write a user-defined function that does the following:
Takes in zero arguments, and returns a basketball struct.
The function will ask the user to enter values for each of
basketball
basketball readElements(void)
{
basketball b;
printf( );
scanf( , b.style);
printf( );
scanf( lf , &b.radius);
printf( );
scanf( lf , &b.weight);
return b;
}
basketball readElements(void) void printElements(basketball b)
{ {
basketball b; printf( \ , b.style);
printf( ); printf( lf\ , b.radius);
scanf( , b.style); printf( lf\ , b.weight);
printf( ); }
scanf( lf , &b.radius);
printf( );
scanf( lf , &b.weight); It is possible to return an
return b;
}
entire struct. Unlike arrays,
ALL values are copied.
int main()
{
basketball b1 = readElements();
printElements(b1);
return 0;
}
yapacagim
.
ilene
hell Zeynep
why
the dur
dagan
.
Neyapmam
Mike
feeling
m'
man
i am yasmam mi
gonna
i rtaiti yor
'
oilman beni
.
people tephra no
-
these
void swap(struct foo input)
{
int tmp = input.a;
struct foo { input.a = input.b;
input.b = tmp;
int a, b;
}
};
int main()
{
struct foo f1 = {1, 2};
printf( , f1.a, f1.b);
swap(f1);
printf( , f1.a, f1.b);
return 0;
}
void swap(struct foo input)
{
int tmp = input.a; What is the output?
input.a = input.b; Before swap: 1 2
input.b = tmp;
} After swap: 1 2
F1 is copied
int main() into input.
{
struct foo f1 = {1, 2};
printf( , f1.a, f1.b);
swap(f1);
printf( , f1.a, f1.b);
return 0;
}
typedef struct foo {
int a, b;
} foo;
m1 m2 m3
monkey *start;
monkey m1, m2, m3;
strcpy(m1.name, );
strcpy(m2.name, );
strcpy(m3.name, );
m1 m2 m3
monkey *start;
monkey m1, m2, m3;
m1.weight = 300;
m2.weight = 150;
m3.weight = 120;
m1 m2 m3
300 150 120
monkey *start;
monkey m1, m2, m3;
strcpy(m1.name, );
strcpy(m2.name, );
strcpy(m3.name, );
m1.weight = 300;
m2.weight = 150; start = &m1;
m3.weight = 120;
m1.next = &m2;
m2.next = &m3;
m3.next = NULL;
m1 m2 m3
300 150 120
Linked List Traversal
Starting at the first node, visit every subsequent
node until the final node is reached.
Linked List Traversal
monkey *p;
int count = 0; /* count monkeys */
element
Madness equal to first
the struct .
count = count + 1;
printf( \ , count, p->name);
}
m1 m2 m3
300 150 120
monkey *p;
int count = 0; /* count monkeys */
for (p = start; p != NULL; p = p->next)
{
count = count + 1;
printf( \ , count, p->name);
}
Console
Monkey 1 is Donkey.
m1 m2 m3
300 150 120
monkey *p;
int count = 0; /* count monkeys */
for (p = start; p != NULL; p = p->next)
{
count = count + 1;
printf( \ , count, p->name);
}
Console
Monkey 1 is Donkey.
m1 m2 m3
300 150 120
monkey *p;
int count = 0; /* count monkeys */
for (p = start; p != NULL; p = p->next)
{
count = count + 1;
printf( \ , count, p->name);
}
Console
Monkey 1 is Donkey.
Monkey 2 is Diddy.
m1 m2 m3
300 150 120
monkey *p;
int count = 0; /* count monkeys */
for (p = start; p != NULL; p = p->next)
{
count = count + 1;
printf( \ , count, p->name);
}
Console
Monkey 1 is Donkey.
Monkey 2 is Diddy.
Monkey 3 is Dixie.
m1 m2 m3
300 150 120
monkey *p;
int count = 0; /* count monkeys */
for (p = start; p != NULL; p = p->next)
{
count = count + 1;
printf( \ , count, p->name);
}
Console
Monkey 1 is Donkey.
p
Monkey 2 is Diddy.
done traversing! Monkey 3 is Dixie.
m1 m2 m3
300 150 120
Linked Lists & Functions
Pass a linked list into a function as an argument.
Implement traversal as a function and return the
number of nodes that were traversed.
Traverse function:
int main ()
{
strcpy(m1.name, );
monkey *start; strcpy(m2.name, );
monkey m1, m2, m3; strcpy(m3.name, );
m1.weight = 300;
int num; m2.weight = 150;
m3.weight = 120;
num = traverse(start); start = &m1;
m1.next = &m2;
printf( , num); m2.next = &m3;
m3.next = NULL;
return 0;
}
More Examples
typedef struct element {
int num;
struct element *next;
} element;
int main ()
{
element e1, e2, e3, e4, *current;
e1.num = 1; e2.num = 2; e3.num = 3; e4.num = 4;
e1.next = NULL; e2.next = &e3; e3.next = &e4; e4.next = &e1;
current = &e2;
while (current != NULL) {
printf( , current->num);
current = current->next;
}
return 0;
}
element e1, e2, e3, e4, *current;
e1.num = 1; e2.num = 2; e3.num = 3; e4.num = 4;
e1.next = NULL; e2.next = &e3; e3.next = &e4; e4.next = &e1;
current = &e2;
element e1, e2, e3, e4, *current;
e1.num = 1; e2.num = 2; e3.num = 3; e4.num = 4;
e1.next = NULL; e2.next = &e3; e3.next = &e4; e4.next = &e1;
current = &e2;
element e1, e2, e3, e4, *current;
e1.num = 1; e2.num = 2; e3.num = 3; e4.num = 4;
e1.next = NULL; e2.next = &e3; e3.next = &e4; e4.next = &e1;
current = &e2;
current = &e2;
while (current != NULL) {
printf( , current->num);
current = current->next;
}
Console
2 3 4 1
Dynamic
Linked list allocation
Recall dynamic array allocation for primitives (int, double, char, etc.)
int size;
char *array; /* 1. Pointer to character array */
printf( );
scanf( , &size);
/* 2. Allocate array dynamically using calloc */
array = (char*) calloc(size, sizeof(char));
/* 3. Use array normally */
Notice!
Our node has no identifier.
We access it using a pointer.
monkey *first, *current;
int addAnother;
first = (monkey*) calloc(1, sizeof(monkey));
current = first;
printf( );
scanf( , current->name);
printf( );
scanf( lf , ¤t->weight);
280
So far so good?
monkey *first, *current;
int addAnother;
first = (monkey*) calloc(1, sizeof(monkey));
current = first;
printf( );
scanf( , current->name);
printf( );
scanf( lf , ¤t->weight);
printf( );
scanf( , &addAnother);
while (addAnother)
{
current->next = (monkey*) calloc(1, sizeof(monkey));
current = current->next;
280
while (addAnother) {
current->next = (monkey*) calloc(1, sizeof(monkey));
current = current->next;
printf( );
scanf( , current->name);
Fill node as usual
printf( );
scanf( lf , ¤t->weight);
280 450
while (addAnother) {
current->next = (monkey*) calloc(1, sizeof(monkey));
current = current->next;
printf( );
scanf( , current->name);
printf( );
scanf( lf , ¤t->weight);
printf( );
scanf( , &addAnother);
}
280 450
while (addAnother)
{
current->next = (monkey*) calloc(1, sizeof(monkey));
current = current->next;
printf( );
scanf( , current->name);
printf( );
scanf( lf , ¤t->weight);
printf( );
scanf( , &addAnother);
}
280 450
while (addAnother)
{
current->next = (monkey*) calloc(1, sizeof(monkey));
current = current->next;
printf( );
scanf( , current->name);
printf( );
scanf( lf , ¤t->weight);
printf( );
scanf( , &addAnother);
}
280 450
while (addAnother)
{
current->next = (monkey*) calloc(1, sizeof(monkey));
current = current->next;
printf( );
scanf( , current->name);
printf( );
scanf( lf , ¤t->weight);
printf( );
scanf( , &addAnother);
}
current->next = NULL;
Structured Data in C
2D arrays (static VS dynamic)
Arrays of strings
Structs, Linked Lists