CoderDojo Linz
CoderDojo is a worldwide organization of free programming clubs for kids. This account is for the CoderDojo in Linz (Austria).
#include <stdio.h>
#include <stdbool.h>
// These are "global variables" of different types.
// They are called "global" because they can be used in
// all functions.
double floatingpoint = 4.2;
int integer = 42;
char character = 'a';
bool boolean = true;
struct values { int a, b, c; } v = { 1, 2, 3 };
int main(void) {
printVariables();
}
void printVariables() {
printf("Variable values: %f, %d, %c, %d, {%d, %d, %d}",
floatingpoint, integer, character, boolean, v.a, v.b, v.c);
}
// These are "global variables" of different types.
// They are called "global" because they can be used in
// all functions.
const floatingpoint: number = 4.2;
const integer: number = 42;
const character: string = 'a';
const boolean: boolean = true;
// JavaScript has no C-like structs
function main(): void {
printVariables();
}
function printVariables(): void {
console.log("Variable values: "
+floatingpoint+', '+integer+', '+character+', '+boolean);
}
main();
#include <stdio.h>
#define BYTE unsigned char
// A string is in fact a "pointer" to memory on the heap.
char *greeting = "Hello World!";
// An array is in fact a "pointer" to memory on the heap.
BYTE *data;
int i;
// Lets declare a pointer to a structure
typedef struct { double x, y, z; } vector;
vector *v;
int main(void) {
// Passing a string to a function means passing a pointer.
puts(greeting);
// Alloc memory on the heap and let v point to it
v = malloc(sizeof(vector));
v->x = v->y = v->z = 42.0;
printf("Vector points to %f / %f / %f", v->x, v->y, v->z);
free(v); // Free heap memory. v becomes invalid.
// Alloc array on the heap and initialize it
data = malloc(3);
for(i = 0; i < 3; i++) { data[i] = i + 1; }
free(data); // Free heap memory
}
// JavaScript has a separate data type for strings
const greeting: string = "Hello World!";
// An array is a reference to the heap
let data: number[];
let i;
// Lets declare a reference to an object
interface Vector { x: number; y: number; z: number }
let v: Vector;
((): void => {
// Passing a string to a function means passing a reference.
console.log(greeting);
// Allocate a JavaScript object on the heap
v = { x: 1, y: 2, z: 3 };
console.log('Vector points to '+v.x+'/'+v.y+'/'+v.z);
// No need to free memory. Done by JS automatically.
// Allocate JS array on the heap
data = []; // No fixed size in JS
for(i = 0; i < 3; i++) { data.push(i + 1); }
// No need to free memory. Done by JS automatically.
})();
// Pointers can point to structures
// which contain pointers to structures
// which contain pointers to structures...
typedef struct {
char *street;
char *city;
} address;
typedef struct {
char *firstName;
char *lastName;
address *address;
int age;
} person;
person *p;
int main(void) {
p = malloc(sizeof(person));
p->age = 42;
p->firstName = "Foo";
p->lastName = "Bar";
p->address = malloc(sizeof(address));
p->address->street = "Somewhere";
p->address->city = "Anywhere";
free(p->address);
free(p);
}
// References can refer to objects
// which contain references to objects
// which contain references to objects...
interface Address {
street: string;
city: string;
};
interface Person {
firstName: string;
lastName: string;
address?: Address;
age: number;
};
let p: Person;
(() => {
p = {
age: 42,
firstName: 'Foo',
lastName: 'Foo'
};
p.address = {
street: 'Somewhere',
city: 'Anywhere'
};
console.log('Done!');
})();
// Structure can recursively point to elements
// of the same type. Here you see a classic data
// structure in programming: A "tree" structure.
// https://en.wikipedia.org/wiki/Tree_(data_structure)
typedef struct {
struct node *left;
struct node *right;
int value;
} treeNode;
treeNode *leftLeaf;
treeNode *rightLeaf;
treeNode *rootNode;
int main(void) {
leftLeaf = malloc(sizeof(treeNode));
leftLeaf->value = 1;
rightLeaf = malloc(sizeof(treeNode));
rightLeaf->value = 3;
rootNode = malloc(sizeof(treeNode));
rootNode->value = 2;
rootNode->left = leftLeaf;
rootNode->right = rightLeaf;
free(rootNode->left);
free(rootNode->right);
free(rootNode);
}
// Structures can recursively reference elements
// of the same type. Here you see a classic data
// structure in programming: A "tree" structure.
// https://en.wikipedia.org/wiki/Tree_(data_structure)
interface TreeNode {
left?: TreeNode;
right?: TreeNode;
value?: number;
};
let leftLeaf: TreeNode;
let rightLeaf: TreeNode;
let rootNode: TreeNode;
(() => {
leftLeaf = { };
leftLeaf.value = 1;
rightLeaf = { };
rightLeaf.value = 3;
rootNode = { };
rootNode.value = 2
rootNode.left = leftLeaf;
rootNode.right = rightLeaf;
console.log(rootNode);
})();
#include <stdio.h>
#include <string.h>
char *greeting1;
char *greeting2;
int main(void) {
// Assigning a string (=pointer) does NOT copy the heap memory.
// Note: IMMUTABLE string that cannot change.
greeting1 = "Hello!";
greeting2 = greeting1;
puts(greeting2);
greeting1 = greeting2 = NULL;
// Allocate heap memory that CAN change (MUTABLE)
// and copy some text into allocated heap.
greeting1 = malloc(sizeof(char) * 4);
strcpy(greeting1, "Hi!");
// Again, assigning a string (=pointer) does
// NOT copy the heap memory.
greeting2 = greeting1;
// Changing greeting1 ALSO changes greeting2 because
// both point to the same memory.
greeting1[0] = 'h';
puts(greeting2);
free(greeting1);
}
let greeting1: string;
let greeting2: string;
(() => {
// JS handles memory for string for you. You do not
// see the details. String in JS are always IMMUTABLE.
greeting1 = 'Hello!';
greeting2 = greeting1;
console.log(greeting2);
greeting1 = greeting2 = undefined;
// JavaScript does NOT have a mutable string
greeting1 = 'Hi!';
greeting2 = greeting1;
// If we change greeting1, greeting2 is NOT changing, too.
greeting1 = 'h' + greeting1.substr(1);
console.log(greeting2);
console.log('Done');
})();
#include <stdio.h>
#include <string.h>
typedef unsigned char BYTE;
BYTE *values1;
BYTE *values2;
BYTE i;
#define SIZE 3
int main(void) {
// Allocate array of numbers and write values into it.
values1 = malloc(SIZE);
for(i = 0; i < SIZE; i++) { values1[i] = i; }
// Assignment does NOT copy the content of the array
values2 = values1;
// This time, we want to COPY THE CONTENT of the
// memory on the heap.
values2 = malloc(SIZE);
memcpy(values2, values1, SIZE);
free(values2);
free(values1);
}
let values1: number[];
let values2: number[];
let i: number;
const SIZE = 3;
(() => {
// Allocate array of numbers and write values into it.
values1 = [];
for(i = 0; i < SIZE; i++) { values1[i] = i; }
// Assignment does NOT copy the content of the array
values2 = values1;
// This time, we want to COPY THE CONTENT of the
// memory on the heap.
values2 = values1.slice(); // in modern JS: [...values1]
console.log('Done');
})();
#include <stdio.h>
int main(void) {
// Declare two LOCAL variables. They are only
// accessible in "main".
int a = 21;
int b = 21;
// The parameters values of a and b are COPIED
// onto the stack for "add".
int sum = add(a, b);
printf("%d + %d = %d", a, b, sum);
}
int add(int a, int b) {
// Note that a, b, and result are LOCAL variables in "add".
// They are stored on the stack.
int result = a + b;
return result;
// We do NOT need to free stack memory.
// This is done automatically.
}
function main(): void {
// Declare two LOCAL variables. They are only
// accessible in "main".
const a = 21;
const b = 21;
// The parameters values of a and b are COPIED
// onto the stack for "add".
const sum = add(a, b);
console.log(a + ' + ' + b + ' = ' + sum);
}
function add(a: number, b: number): number {
// Note that a, b, and result are LOCAL variables in "add".
// They are stored on the stack.
const result = a + b;
return result;
// We do NOT need to free stack memory.
// This is done automatically.
}
main();
console.log('Done');
function main(): void {
const numbers: number[] = [];
for (let i = 0; i < 3; i++) { numbers[i] = i; }
// Passing numbers to sum does NOT copy the array,
// only the reference is copied.
const result = sum(numbers);
console.log(result);
}
function sum(numbers: number[]): number {
let result = 0;
for(let i = 0; i < numbers.length; i++) { result += numbers[i]; }
return result;
}
main();
console.log('Done');
void main() {
int *numbers = malloc(sizeof(int) * 3);
for (int i = 0; i < 3; i++) { numbers[i] = i; }
// Passing numbers to sum does NOT copy the array,
// only the pointer is copied.
int result = sum(numbers, 3);
printf("%d", result);
free(numbers);
}
int sum(int *numbers, int length) {
int result = 0;
for(int i = 0; i < length; i++) { result += numbers[i]; }
return result;
}
(() => {
let a = 1;
if (1 === 1) {
// The next "a" is different from the "a" above
// because it is inside a new block.
let a = 2;
if (1 === 1) {
// The next "a" is different from the "a" above
// because it is inside a new block.
let a = 3;
console.log(a);
}
console.log(a);
}
console.log(a);
console.log('Done');
})();
const maxValue = 13;
function fibonacci(last: number, secondLast: number): void {
const next = last + secondLast;
if (next > maxValue) return;
console.log(next);
fibonacci(next, last);
}
console.log(1);
console.log(1);
fibonacci(1, 1);
console.log('Done');
By CoderDojo Linz
Heap, stack and recursion are three important, fundamental principles in computer programming. In this presentation, you learn the basics of the different memory types and explore how recursive algorithms work.
CoderDojo is a worldwide organization of free programming clubs for kids. This account is for the CoderDojo in Linz (Austria).