{"id":23200482,"url":"https://github.com/loreina/comp206","last_synced_at":"2026-01-18T08:03:32.306Z","repository":{"id":268619901,"uuid":"153349801","full_name":"loreina/comp206","owner":"loreina","description":null,"archived":false,"fork":false,"pushed_at":"2018-12-23T04:20:57.000Z","size":29,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-05T09:28:48.263Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loreina.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-16T20:28:27.000Z","updated_at":"2019-04-08T19:17:25.000Z","dependencies_parsed_at":"2024-12-17T22:45:05.966Z","dependency_job_id":null,"html_url":"https://github.com/loreina/comp206","commit_stats":null,"previous_names":["loreina/comp206"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/loreina/comp206","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loreina%2Fcomp206","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loreina%2Fcomp206/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loreina%2Fcomp206/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loreina%2Fcomp206/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loreina","download_url":"https://codeload.github.com/loreina/comp206/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loreina%2Fcomp206/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28533764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-18T15:11:22.792Z","updated_at":"2026-01-18T08:03:32.283Z","avatar_url":"https://github.com/loreina.png","language":null,"readme":"#### COMP 206 Fall 2018\n\n# Table of contents\n1. [Operating system](#operating-system)\n2. [Linux](#linux)\n3. [Bash](#bash)\n4. [C](#c)\n    1. [Pointers](#pointers)\n    2. [2D arrays](#2d-arrays)\n5. [Memory](#memory)\n6. [BMP images](#bmp-images)\n\n# Operating system\n\n#### Definition\n- software that supports a computer's basic functions\n  - ie. scheduling tasks, executing applications, controlling peripherals\n- OS has \"control\" over application programs by deciding when they start/stop, which users can access, which resources can be accessed (files, network, etc)\n- OS must launch every other application\n\n## Computer hardware to OS\n\n### The beginning: hooting up\n- first device to get power is a BIOS or firmware interface\n- BIOS is a special piece of hardware that manages the lowest level\n- BIOS selects which code to start running next, based on a priority over bootable media (hard drives, USB keys, DVD, the network) \n\n### The middle: a boot loader\n- a disk is bootable if it has a particular sequence of data at its very beginning, the Master Boot Record (MBR)\n- BIOS reads each device in order until it finds one that's indicated \"bootable\"\n- BIOS can load an OS and begin its execution, but very often there's a small piece of software known as boot loader indicated in MBR\n  - a common boot loader for use with Linux is called **GNU GRand Unified Bootloader (GRUB)**\n- boot loader can provide some more flexibility and a nice interface to let you choose an OS, which the boot loader then executes\n\n### The end (of the beginning)\n- the **Kernel** is the part of the OS that runs first and always\n- Kernel is responsible for loading and running all other programs\n- Kernel gets to create the spec of what's allowed, enforce security, kill other jobs, provide access to hardware, etc.\n\n# Linux\n\n## What is Linux?\n- an operating system based on the Linux kernel written by Linux Torvalds in 1991\n  - Linux kernel was a reimplementation of Unix designed from the start to be **free and open source**\n- Linux is hard to define because some people have made new versions from this kernel that others don't agree on\n- Linux is still developed by Linux Torvalds, along with the worldwide community\n\n## Unix/Linux philosophy\n- multiuser/multitasking\n- toolbox approach\n- flexibility/freedom\n- conciseness\n- *everything* is a file\n- file system has places; processes have life\n- designed by programmers, for programmers\n\n## Unix OS components\n\n**Kernel**\n- login\n- task switching, multi-processing\n- basic interface with user and programs\n- drivers, run-time stack, heap\n\n**File system**\n- defines the way the disk drive is formatted\n- file allocation table (FAT)\n- data structure on disk that makes files feel *real*\n- reading/writing to disk and peripherals\n- user commands to interact with files\n\n**Shell**\n- a more \"advanced\" user interface\n- has a global memory\n- scriptable to produce complex behaviour\n\n**Utilities**\n- additional OS commands and programs\n- third party commands and programs\n- drivers\n\n## Shell as a user interface\n- a shell is a command **interpreter** turns text that you type (at the command line) into actions:\n  - **runs a program (aka command)**\n  - allows you to edit a command line\n  - opens the door for complex ways of chaining commands into larger programs, scripting, etc.\n\n## File system: an interface to the disk\n- `bin`: `sh`, `date`, `csh`\n- `etc`: `passwd`, `group`\n- `lib`: `libc.so`\n- `usr`: `bin`, `man`, `local`\n  - `local`: `bin`, `man`, `src`\n- `dev`: `ttya`, `null`\n- `tmp`\n- `home`: `frank`, `linkdadb`, `rfunk`\n  - `lindadb`: `mail`, `bin`, `src`\n\n## Commands to know\n- `ls`: list files\n- `cd`: change directory\n- `pwd`: where am I now? (present working directory)\n- `mv`: move files or directories\n- `find`: search for files with given properties\n- `chmod`: change permissions\n- `cp`: copy files or directories\n- `cat`: concatenate input files\n- `echo`: copy input to output\n- `grep`: filter input based on a pattern\n- `tr`: translate inputs to outputs\n- `sort`: sort inputs, then output\n- `ps`: display running processes (once)\n- `top`: display the running processes (continuous) and resource usage\n- `uname`: print system info (which Linux version)\n- `ssh`: remotely connect to another computer\n\n## Running a program\n- type the program's name, followed by command line args\n- ie.  `$ ls -l /bin`\n  - program name: `ls`\n  - first arg: `-l`\n  - second arg: `/bin`\n\n## Defaults for I/O\n- when a shell runs a program for you:\n  - standard input is your keyboard\n  - standard output is your screen/window\n  - standard error is your screen/window\n\n### Terminating standard input\n- if standard input is your keyboard, you can type stuff in that goes to a program\n- to end the input, type ctrl+D on a line by itself, ending the input *stream*\n- shell is a program that reads from stdin\n\n### Input redirection\n- shell can attach things other than your keyboard to stdin\n- a file, using the \"\u003c\" operator:\n  - ie. `$ grep pattern \u003c search_file.txt`\n    - the contents of the file are fed to a program as if you typed it\n  - ie. `$ sort \u003c nums.txt`\n    - sort the lines in the file nums and send the result to stdout\n- the output of another commands, using the \"|\" operator:\n  - ie. `$ ls | grep`\n    - the output of another program is fed as input as if you typed it\n    - both programs run simultaneously to continue transmitting info over their \"pipe\"\n\n### Output redirection\n- shell can attach things other than your screen to stdout (or stderr)\n- a file using the \"\u003e\" operator:\n  - ie. `$ ls \u003e file_info.txt\"\n    - the output of a program is stored in file\n- the input of another program, using a pipe as we have seen on the prev slide\n\n### Output and output append\n- the command `$ ls \u003e foo.txt`\n  - creates a new file named foo, overrides any existing file named foo\n- if you use `\u003e\u003e`, the output will be appended, leaving any contents that were prev in the file and adding the new output at the end\n  - ie. `$ ls /etc \u003e\u003e foo.txt`\n  - ie. `$ ls /usr \u003e\u003e foo.txt`\n- `\u003e\u003e` still creates the file if it wasn't there previously\n\n### Errors\n- sometimes we don't want them ending up in our redirect file, so the default behaviour `\u003e` is that errors stay on the terminal and only stdout enters the file\n- however, the shell is powerful an we can decide on what goes where:\n  - `1\u003e`: send stdout only (same as `\u003e`)\n  - `2\u003e`: send stderr only (stdout might stay on terminal)\n  - `\u0026\u003e`: send both stdout and stderr\n- you can add both `1\u003e` and `2\u003e` giving diff files\n  - if you name the same file, you'll only get stdout\n\n## Pipes\n- a **pipe** is a holder for a stream of data\n- pipe can be used to hold the output of one program and feed it to the input of another\n\n### Asking for a pipe\n- separate 2 commands with the `|` character\n- let the shell do all the work!\n  - ie. `$ ls | sort`\n  - ie. `$ ls | sort \u003e sortedls`\n\n## Text editing in Linux\n- editors inside the shell's window:\n  - vim, emacs, pico, nano\n- window-based editors:\n  - gedit, sublime, vs code, eclipse\n\n## Important Linux paths\n- `/`: the root of the file system\n  - every other file falls below `/` in the directory tree\n- `~`: current user's home directory\n- `.`: right here when it starts a path, and nothing if it occurs within a path (2nd case just a convenience for programming)\n- `..`: parent directory\n\n## Job control\n- shell allows you to manage *jobs* (aka running processes)\n  - place jobs in the background\n  - move a job to the foreground\n  - suspend a job\n  - kill a job\n\n### Background jobs\n- if you follow a command line with `\u0026`, the shell will run the job in the background\n  - you don't need to wait for the job to complete, you can type in a new command right away\n  - you can have a bunch of jobs running at once\n  - you can do all this with a single terminal\n\n## Suspend/kill foreground jobs\n- suspend with `ctrl+Z`\n  - job is stopped, not dead\n  - job will show up in the `jobs` output\n- kill with `ctrl+C`\n  - it's gone...\n\n### Moving a job back to the foreground\n- the `fg` command will move a job to the foreground\n  - you give `fg` a job number as reported by `jobs` preceded by a `%`\n    - ie. `fg %1 `\n  \n## Wildcards\n- when you type in a command line, the shell treats some characters as special\n- these special characters make it easy to specify filenames\n- the shell processes what you give it, using the special characters to replace your command line with one that includes a bunch of file names\n\n### * character\n- `*` matches anything\n- if you give the shell `*` by itself as a command line arg, the shell will remove the `*` and replace it with all filenames in the current dir\n  - ie. `a*b` matches all files in the current dir that start with `a` and end with `b`\n\n### Other characters\n- `?`: matches any single char\n  - ie. `ls Test?.doc`\n- `[abc...]`: matches any of the enclosed characters\n  - ie. `ls T[eE][sS][tT].doc`\n- `[!abc...]`: matches any character except those listed\n  - ie. `ls [!0-9]*`\n\n## Quoting\n- If we don't want characters to mean their special form in the command line, surround a string with double quotes\n  - ie. `echo here is a star \"*\"`\n\n### Quoting exceptions\n- some special characters are **not ignored** even if inside double quotes:\n  - `$`: prefix for var names\n  - `\"`: the quote char for itself\n  - `\\`: for multiple things\n  - `$(())`: for math\n- command substitutions using `$(...)` or `..` are still evaluated\n\n### Single quotes\n- the strongest version of quotes, nothing at all is \"escaped\"\n  - `$var` is not replaced by their value\n  - `\\` is no longer special\n  - math `$(())` does not work\n  - command substitution using `$(...)` does not work\n- for syntax, you can use single quotes just like double quotes\n\n# Bash\n\n## Creating a shell program\n- shell programs are written in text files, named `.bash` by convention\n- any series of commands you can type into the terminal one by one can also form a shell program\n  - a new line starts whenever you press enter\n\n### How to run a shell program\n- run a shell program in one of several ways:\n  - `$ bash program.bash`\n  - `$ . program.bash`\n  - `$ source program.bash`\n\n## First line of a bash program\n- `#!/bin/bash`: the standard first line for every bash script\n- known as a shebang sequence to indicate which shell we intend if bash is not the shell in terminal being used\n\n## Shell variables\n- shell keeps track of a set of parameter names and values\n- assign variables with command prompt\n  - ie. `# my_var=Hello`\n- access variables with dollar sign\n  - ie. `# echo $my_var`\n- some of these are special parameters that determine behaviour of the shell\n- some are used to build program logic\n- variable with an assignment command is a shell *builtin* command:\n  - ie. `# HOME=/etc`\n- variable name syntax\n  - no spaces in var name, between var name and equals, between equals and value, within value\n  - to use spaces in values, enclose them in quotes\n    - ie. `# NEWVAR=\"blah blah blah\"`\n  \n### set command (shell builtin)\n- the **set** command with no parameters prints out a list of all the shell variables\n\n## Some bash variables\n- `pwd`: current working directory\n- `path`: list of places to look for commands\n- `home`: user's home directory\n- `mail`: where your email is stored\n- `term`: what kind of terminal you have\n- `histfile`: where your command history is saved\n- `PS1`: the string to be used as the command prompt\n\n### PS1\n- the `PS1` shell var is your command line prompt\n- is a string\n  - ie. `# PS1=\"# \"`\n\n## Fancy bash prompts\n- `\\t`: is replaced by the current time\n- `\\w`: is replaced by the current directory\n- `\\h`: is replaced by the hostname\n- `\\u`: is replaced by the username\n- `\\n`: is replaced by a new line\n\n## Capturing command output in a variable\n- use the back-tick operator to skip the file system (efficiency of memory vs disk) and reuse the output within our bash program\n  - format: `#  var=`command``\n  - annything that `# command` alone would put to the terminal is now stored as the value of a var\n  - access: `$var`\n\n## Math\n- shell can do simple arithmetic\n- enclose computation: `$((computation))`\n  - ie. `# a=$((3+5))`\n  - ie. `# echo There are $((60*60)) seconds in an hour`\n\n## Program exit codes\n- every process returns an integer value when it terminates\n- part of the Linux process spec\n\n## If statements\n\nCommand | Description\n--- | ---\n`n1 -eq n2` | true if n1 and n2 are **equal**\n`n1 -ne n2 ` | true if n1 and n2 are **not equal**\n`n1 -gt n2` | true if n1 is **greater than** n2\n`n1 -ge n2` | true if n1 is **greater than or equal to** n2\n`n1 -lt n2` | true if n1 is **less than** n2\n`n1 -le n2` | true if n1 is **less than or equal to** n2\n`-z string` | true if string length = **zero**\n`-n string` | true if string length = **non-zero**\n`string1 = string2` | if the strings are **identical**\n`string1 != string2` | if the strings are **not identical**\n`string` | true if string is **not NULL**\n`-r file` | true if it exists and is **readable**\n`-w file` | true if it exists and is **writeable**\n`-x file` | true if it exists and is **executable**\n`-f file` | true if it exists and is a **regular file**\n`-d file` | true if it exists and is a **directory**\n\n### Writing if statements\n\n- `[[ condition ]]` always works\n- `[ condition ]` works on some bash shells, not all\n\n## For \u0026 While Loops\n\n### For loops\n\n**Format**\n\n    for (var) in (list)\n    do\n      (actions)\n    done\n\n**Example**\n\n    $ cat for2.sh\n\n    i = 1\n    weekdays = \"Mon Tue Wed Thu Fri\"\n\n    for day in \"$weekdays\"\n    do\n      echo \"Weekday $((i++)) : $day\"\n    done\n\n    $ ./for2.sh\n\n    Weekday 1 : Mon\n    Weekday 2 : Tue\n    Weekday 3 : Wed\n    Weekday 4 : Thu\n    Weekday 5 : Fri\n\n### While loops\n\n**Format**\n\n    while (condition)\n    do\n      (actions)\n      [continue]\n      [break]\n    done\n\n**Example**\n\n    #!/bin/bash\n\n    i = `wc -c \u003c $1`;\n\n    while test $i -lt $2\n    do\n      echo -n \"0\" \u003e\u003e $1;\n      i = `wc -c \u003c $1`;\n    done\n\n    % ./fill ass1.c 100\n\n## Shell conditional structure\n- shell conditionals are slightly different than other programming languages\n- they rely on a program to run and give an output code that can be evaluated\n- contrasting Bash and C, the if statement looks directly at built-in vars with equality, greater than, less than operators as a core part of the language\n- mush used and give us our first building block to make larger programs and deploy our code for software systems\n\n# C\n\n## Program elements\n- `#include`: way we ask for language functionality to be \"turned on\"\n  - same as import in Java or Python\n- `int main()`: indicates this is the first function to run in a prog\n- `printf()`: basic method to write to terminal (stdout)\n- `\\n`: new line\n\n## Compiling/running C programs\n- compiling means to create a prog from source code\n  - `$ gcc hello_world.c`\n- running means asking the terminal to exec the prog\n  - `$ ./a.out`\n\n## History of C\n- invented in 1972 by Denis Ritchie\n- used to program early UNIX versions\n- defined by the standed in K\u0026R text first version\n- standardized by ANSI organization as C90\n\n## About C\n- general purpose, imperative, typed language designed to support cross-platform code with minimal reqs\n- a compiled language\n  - source code cannot be run directly\n  - needs to be processed by a *compiler* which produces machine code\n- sign of a compiled language:\n  - after compilation, the programs can run even if the compiler is not present on the system\n  - important for creative low-level components like the kernel\n- by having a compiler available for each machine, the identical C code is guaranteed to work everywhere, \"cross platform\"\n\n## C philosophy\n- C statements are close to the low level features provided by the computer and OS\n- C gives us access to low level without getting in the way too much\n- The programmer has the power:\n  - access to low level memory\n  - allowed to change the types used to interpret data\n  - language often provides several ways to accomplish the same operation\n- advantage: C code is easily portable across systems, even for low level ops\n- risks:\n  - programmer is free to make mistakes\n  - C code can also sometimes be \"ugly\"\n  - C code can be unsafe to run\n\n## C datatypes\n- C provides a number of built-intypes\n  - `int`: integers\n  - `float`: floating point numbers of single precision\n  - `double`: floating point numbers of double precision\n  - `char`: characters to represent text\n- modifiers to give more flexibility\n  - `short`, `long`: change the number of bits used to represent an int\n  - `signed`, `unsigned`: determine whether one can represent negative numbers\n  - pointers store addresses in the computer's memory\n\n## Function components\n- a return type (can be void)\n- a name (must be unique in the prog)\n- an arg list with types and var names (can be empty)\n- a function body enclosed in {}\n\n### C function properties\n- name must be unique\n- pass arguments by value\n- define a local scope for variables\n\n## Arrays \n\n### Data types\n- in order to store more than one value within the same variable, C provides simple arrays:\n  - ie. `int hourly_prices[24];`\n- provide the size when declaring the variable, but it can be left off when specifying a function argument\n  - ie. `int main( int argc, char *argv[] )`\n    - the size is decided by the calling function (e.g., here we can type any number of arguments\n\n### Array view in memory\n- array variable gives us “space” to store N elements of the declared type\n- In C this does not come with much extra help:\n  - `array.len()` is not defined\n  - `array.sort()` is not defined\n  - `sizeof(array)` is a dangerous operation\n\n### Array sizes\n- C does not provide any safety mechanisms for programmers regarding array length\n- it's possible to accidentally process past the end of the array\n\n### Beyond the end of an array\n- you can see any of the follow errors:\n  - `*** stack smashing detected ***: ./a.out terminated`: Aborted (core dumped)\n    - The program continues to run, but some other variable has been changed and problem occur later\n  - `Segmentation fault` (core dumped)\n    - There may be no detectable change and everything seems fine (if you are very lucky/unlucky)\n\n### Array best practices\n- define a constant for the array size to setup array and limit any time you use the data\n      \n      const int array_length = 10;\n      float account_balances[array_length]; for( pos=0; pos\u003carray_length; pos++ )\n\n- use \"pre-processor replacement\" to specify size\n\n      #define array_length 10\n      float account_balances[array_length]; \n      for( pos=0; pos\u003carray_length; pos++ )\n\n- keep the length of your array in a variable\n- more powerful because the array can take different lengths at run-time\n\n      int array_length = 10;\n      float account_balances[array_length];\n      for( pos=0; pos\u003carray_length; pos++ )\n\n### Array sorting\n- `pos`: each position in the array\n- `curr`: current value at `pos`\n- `min_val`, `min_pos`: position of the minimal element from `pos` to the end\n\n## Binary\n- find the decimal value of a binary number:\n  - sum of 2\u003csup\u003ei\u003c/sup\u003e for every \"1\", where `i` is the position in the number, with 0 on the right\n    - ie. 1101 = 2\u003csup\u003e0\u003c/sup\u003e + 2\u003csup\u003e2\u003c/sup\u003e + 2\u003csup\u003e3\u003c/sup\u003e = 1 + 4 + 8 = 13\n- find the binary value of a decimal number:\n  - while `decimal_val` not zero:\n    - find the largest power 2 that is less than or equal and add a “1” in the binary number in position i, where i is the position in the number, with 0 on right\n\n## What's in memory\n- the Kernel process\n- the Shell process\n- your program's process\n  - the program's machine code\n  - program variables\n  - required libraries\n  - bookkeeping info\n\n### Variables space\ndescription | type | bits | range\n--- | --- | --- | ---\ninteger | short | 16 | +/- 32k\ninteger | int | 32 | +/- 2.1b\ninteger | long | 64 | +/- 9.2 x 10\u003csup\u003e18\u003c/sup\u003e\nfloating point | float | 32 | +/- 10\u003csup\u003e38\u003c/sup\u003e\nfloating point | double | 64 | +/- 10\u003csup\u003e308\u003c/sup\u003e\nfloating point | long double | 128 | +/- 10\u003csup\u003e4932\u003c/sup\u003e\ncharacter | char | 8 | -127 to 128\ncharacter | unsigned char | * | 0 to 255\npointer | char* | 64 | 0 to 1.8 x 10\u003csup\u003e19\u003c/sup\u003e\npointer | int* (etc) | |\n\n### The type matters for real data\n- match between the meaning of underlying data and the available tools and data types from C\n  - ie. 16-bit colour image made to be small to work on old game consoles:\n    - red takes 4 bits\n    - green takes 4 bits\n    - blue takes 4 bits\n    - transparency takes 4 bits\n    - choices: 2 chars, 1 short, 3 chars, 1 int, etc.\n\n### Arrays and memory\n- arrays take multiple \"slots', each of the underlying type\n  - ie. `float array[2];`\n- guaranteed to be stored in order\n- number as you specify on array creation and does not change\n\n## C strings\n- arrays of characters\n  - ie. `char name[100] = \"David\";`\n- each element is a character stored using the ASCII table\n  - a mapping between our printable letters and the 0s and 1s in memory\n- must be \"null terminated\" with the special `\\0` NULL value, with integer representation 0\n- allows things like `printf()` to output just the data you want\n\n### Strings in memory\n- char type is really an 8-bit int\n\n## C code to work with single characters\n- single quotes for literals\n  - `char char_variable = 'w';`\n- math allows moving alphabetically forward and backwards, finding relative positions\n  - `char_variable++;` (it's now = 'x')\n  - `char_variable - 'a'` (tells you what position in alphabet, 23 here)\n- logic works via alphabetical order\n  - `char_variable == 'x'` (evals true)\n  - `char_variable \u003e 'z'` (evals false)\n\n## C code to work with char arrays\n- double quotes for literals\n  - `char str_var[100] = \"hello\";`\n- doesn't work with math\n  - `str_var++;` (error)\n  - `str_var – \"jello\"` (nothing related to 'h' – 'j')\n- logic operators don't work\n  - `str_var == \"hello\"` (incorrect)\n  - `str_var \u003e \"jello\"` (incorrect)\n\n## Address operator \u0026\n- variable identifier represents the value of the variable\n- variable identifier preceded with `\u0026` represents the address of the variable\n\n## Pointers\n- a **pointer** is a variable that stores an address\n- must be initialized with a specified address prior to its use\n- pointers allow us to move around our strings (think iterators, lists, indices)\n      char str_var[100] = “Hello”;\n      char *start = str_var;\n      char *mid = str_var+3;\n\n### Pointer syntax\n- declare a non-pointer variable:\n  - `type varname;`\n- declare a pointer with:\n  - `type *varname;`\n  - star can be anywhere between type and var\n  - `varname` holds the value of \"the address of a variable or array of `type`\"\n\n### Dereferencing\n- the primary use of a **pointer** is to access and change the value of the variable that pointer points to\n- value of the variable is represented by preceding the pointer variable identifier by an asterisk (*), which literally means 'value at address'\n- the 'value at address' operator is also called indirection operator or **dereference operator**\n\n      int i = 3;\n      int *p = \u0026i;\n      printf(\"The value of i = %d\\n\", i);\n      printf(\"The value of i = %d\\n\", *p);\n      printf(\"The address of i = %p\\n\", \u0026i);\n      printf(\"The address of i = %p\\n\", p);\n      printf(\"The address of p = %p\\n\", \u0026p);\n\n- `*p` holds the value of `i`\n- `p` holds the address of `i`, aka `\u0026i`\n\n## Pointers vs arrays\n- in some ways, they're interchangeable\n  - an array in C is implemented as the address of its first entry, so we \"point to\" the array\n\n        char array[4] = \"abc\";\n        char *ptr = array;\n\n- in some ways, they differ\n  - the array variable holds the address to the start of this memory always, while the pointer if flexible\n\n        char array[4] = “abc”;\n        char *ptr = array;\n        ptr++; ptr++; ptr++; ptr++; // These work\n\n        array++; // This is an error!\n\n  - an array says how much memory it requires at the beginning\n  - a ptr declaration alone does not request memory to store data\n\n        char array[4];\n        array[0] = ‘a’; // This line is OK\n\n        char *ptr;\n        ptr[0] = ‘a’; // This line may seg fault\n\n## C string using pointers\n- pointing to start of literal or array works\n\n      char *ptr = \"hello\";\n      char str_array[100] = “hello”;\n      char *ptr2 = str_array;\n\n- pointer math moves us around the string and computes distances\n\n      ptr=ptr+3; //Now points to lo\n      ptr = ptr – 1; // Back to llo\n      char *ptr2 = str_array;\n      ptr – ptr2; // Gives position; difference, 2 here\n\n## C Built-in libraries\n- it's important we know how to do operations \"bit-by-bit\"\n- standardized implementations of basic operations are provided as language libraries:\n  - \u003cstdio.h\u003e\n  - \u003cstdlib.h\u003e\n  - \u003cstring.h\u003e\n  - \u003cmath.h\u003e\n\n### \u003cstring.h\u003e\n\n`size_t strlen(const char *str)`\n- Computes the length of the string `str` up to but not including the terminal null character.\n\n`int strcmp(const char *str1, const char *str2)`\n- Compares the string point to, by `str1` to the string pointed to by `str2`\n\n`char *strcpy(char *dest, const char *src)`\n- Copies the string pointed to, by `src` to `dest`\n\n`void *memset(void *str, int c, size_t n)`\n- Copis the character `c` (an unsigned char) to the first `n` charactesr of the string pointed to, by the argument `str`\n\n`char *strcat(char *dest, const char *src)`\n- Appends the string pointed to, by `src` to the end of the string pointed to by `dest`\n\n`char *strstr(const char *haystack, const char *needle)`\n- Finds the first occurence of the entire string `needle` (not including the terminating null character) which appears in the string `haystack`\n\n\n### \u003cstdio.h\u003e\n\n**\u003cstdio.h\u003e** provides built-in functions to work with I/O.\n\n**3 types of I/O**\n\nConsole\n- Keyboard, screen\n- stdin, stdout, stderr\n\nStream\n- Constant stream of data from logical/physical device\n\nFile\n- Reading or writing to file\n\n**Important functions**\n\n`int printf(const char *format, ...)`\n- Sends formatted output to stdout\n\n`int fputs(const char *str, FILE *stream)`\n- Writes a string to the specified stream up to but not including the null character\n\n`int fputc(int char, FILE *stream)`\n- Writes a character (unsigned char) specified by the argument char to the specified stream and advances the position indicator for the stream\n\n`int fprintf(FILE *stream, const char *format, ...)`\n- Sends formatted output to a stream\n\n`char *fgets(char *str, int n, FILE *stream)`\n- Reads a line from the specified stream and stores it into the string pointed to by str. It stops when either (n-1) characters are read, the newline character is read, or the end-of-file is reached, whichever comes first\n\n`int fgetc(FILE *stream)`\n- Gets the next character (an unsigned char) from the specified stream and advances the position indicator for the stream\n\n## fopen(...)\n- returns a \"file pointer\"\n  - NULL (=0) if there was any problem; **always check for this!**\n  - otherwise, it's safe to use the other file operations\n- the mode string indicates what we want to do, so `fopen()` can check that we have the correct permissions\n  - `r`: read only. file must exist previously with read permission\n  - `w`: write only. create new file or overwrite prev contents\n  - `a`: append. create new file or add to end of prev contents\n  - `b`: cn be added to any meaning to interpret the file as binary\n  - `+`: for read and write together\n  \n## Text file formats\n- can be unstructured, for the purposes of human consumption\n  - ie. text version of a novel, your journal, written answers\n  - common extension: `.txt`\n- more interesting for systems: structured text files\n  - ie. C program, BASH program, website, etc.\n- thinking text as data for our computation\n  - goal: allow programs to easily save and restore content, not necessarily easy to read for humans, but also a \"nice to have\"\n  - systems programmers are responsible for creating good file types: how to split up the data, tell where one item ends and another begins, make processing fast\n\n### Text data file examples\n- `.csv`: comma separated values\n- `.html`: hyper text markup language\n- `.md`: markdown\n- `.yaml`: yet another markup language\n- `.json`: javascript object notation\n\n## 2D arrays\n- declared by repeating the square bracket syntax\n  - `char ttt[3][3];`\n- creates an array where each entry is itself an array\n- the type (ie. char) is the same for every entry of the inner array\n- outer array behaves as we expect:\n  - fixed size\n  - always represents the memory of the first entry and can't be moved (ie. no `++`)\n  - elements stored directly after one another\n\n![2D arrays](https://i.imgur.com/SV5xzQl.png)\n\n### Accessing 2D array data\n- for `type array_name[N][M]`\n  - syntax `array_name[i][j]` is used both to read\nand write data at entry `i`, `j`\n- first index can be 0 to N-1, second index can be 0 to M-1\n- in the image:\n  - `ttt[0][0]` evaluates to ‘x’\n  - `ttt[2][2] = ‘o’;` sets bottom-right value\n\n### When to use a 2D array\n- when each \"row\" has the same size always\n\n        int days_in_each_month[2][12] = {\n          { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },\n          { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } \n        };\n\n- often when data looks like a \"table\"\n\n        float grades[number_of_assignments][class_size] = {\n          { 100.0, 99.0, 83.0 },\n          { 99.9, 99.9, 99.8 } \n        };\n\n### What 2D arrays look like in memory\n\n- the system memory is addressed in ascending linear order (1D)\n  - ie. `char[2][3] greetings = { ”hi”, “yo” };`\n\n![2D arrays in memory](https://i.imgur.com/XBgqCza.png)\n\n### When to not use 2D arrays\n- if the data in each entry \"row\" can vary in length\n- if the length of each entry \"row\" isn't known when coding, for example it will change based on user input\n  - ie. `char greetings[4][8] = { “hi”, “yo”, “bonjour”, “hello” };`\n\n![when not to use 2d arrays](https://i.imgur.com/yWtPBaC.png)\n\n### Array of pointers\n- the type of each entry is now `char*`, a single character pointer\n  - ie. `char *greetings[4] = { “hi”, “yo”, “bonjour”, “hello” };`\n- avoids wasting space\n\n![array of pointers](https://i.imgur.com/ZzkDIJn.png)\n\n### How to call functions with 2D arrays\n- `void f( char current_board[3][3] ){` \n- `void f( char current_board[][3] ){`\n- `void f( char(*current_board)[3] ){`\n  - this says “pointer to data of type 3-length char array”\n  - we can note the outer array with unknown size is equivalent to pointer\n  - the brackets around (char*) are essential to distinguish this from an array of pointers\n\n## argv[]\n- type is char* argv[], an array of pointers, each to one of the argument words\n- want the user to be able to type any number of arguments, each of any length and have the result end up properly sorted\n- we can sort “in place” by working only on the pointer values within argv, no need to create a new variable\n\n![argv](https://i.imgur.com/iaZt3Xr.png)\n\n# Memory\n\n## Key thoughts on memory\n- your `a.out` is a file, it takes space on a disk\n- each running process requires system resources\n- when we create systems programs, we have control over how the memory is used\n\n## Elements of a running process\n- text space\n- data segment\n- BSS segment\n- heap\n- stack\n- Kernel space\n- memory mapping\n\n### Statically Sized Parts that come from gcc\n- text space\n  - our runnable machine code\n  - stored in `a.out`\n  - the processor loads these instructions and steps through line by line\n- data segment\n  - elements of fixed size that are known at compile time\n  - stored in `a.out`\n    - ie. string literals\n  - values can't be changed\n- BSS (Blocked Started by Symbol) segment\n  - space to hold \"static\" variables without initial values\n  - filled with zeroes at run time\n  - not actually stored in `a.out`, but only the size needed since there's no initial data\n  - changeable\n\n### Elements that change in size\n- stack\n  - space to store the local variables within each function\n  - stack \"frames\" are created when the function is called, and removed when the function returns\n  - stack variables, including arrays, are temporary and we shouldn't keep pointers to them\n- heap\n  - space for the programmer to control dynamically\n  - where we're allowed to request the most available resources\n  - grows and shrinks at our request\n  - in object oriented languages, used for \"new\" objects\n\n### Others\n- Kernel\n  - we get to see a copy of a portion of the kernel in each process\n  - this is a \"trick\" of the OS to give us low level functionality\n- memory mapping\n  - access to files and libraries the OS connects us to\n\n## Static (global), stack, and heap memory\n\n### Automatically sized arrays\n- these arrays live on the **stack**\n- the size limit is typically quite small\n- good for small stuff, but we need to ask for way more memory\n\n### Stack memory limited\n- when creating pointers, we must think about the stack push-pop behaviour\n  \n### To fix Statically Sized Arrays\n- test with `gcc –DSTATIC_ARRAY_SIZE=number`\n- you can typically get away with much larger sizes, even to the point where you can't practically use the memory provided\n  \n## The heap: dynamically allocated memory\n- provides flexible persistent memory across function calls\n  - ie. `char* createImageData( int width, int height )`\n    - should return a pointer to new memory that can hold pixel data\n    - incorrect to point to a stack variable\n    - if we don't know the size of our bunny ears in advance, we can't use static\n- request for N bypes of heap memory (not initialized):\n  - `void *malloc(size_t numberOfBytes);`\n- request for an array of N elements each with size bytes, and initializes the values all to 0\n  - `void *calloc(size_t num, size_t size_of_each);`\n\n### Allocating useful types\n- `malloc` and `calloc` return a void pointer: `void *`\n- it must be cast before it can be dereferenced\n  \n      int *a = (int *) malloc( sizeof(int) * 40 ); // OR\n      int *a = (int *) calloc(40, sizeof(int));\n\n- the `sizeof()` function simplifies the allocation of memory by calculating the size of the provided data type\n\n### Rules to follow for malloc\n- 3 TYPEs to fill in:\n  - `TYPE1 variable_name = (TYPE2)malloc( sizeof(TYPE3)*number );`\n  - `int *pi = (int*)malloc( sizeof(int) * 1 );`\n- RULE1: TYPE1 matches TYPE2, both are pointer types:\n  - the point of casting is to tell C how we plan to interpret the heap memory allocated for us by malloc\n  - malloc returns `void*` so that it can handle any type\n  - since this is initially empty memory, casting is always safe\n- RULE2: TYPE3 is the de-referenced version of TYPE2\n  - “one less star”\n  - when we dereference the variable with `*variable_name`, C will assume the memory is of the pointer’s underlying type\n\n### Using malloc correctly\n- allocate a single integer on heap\n  - `int *pi = (int*)malloc( sizeof(int) );`\n- allocate an array of 10 integers on heap\n  - `int *my_numbers = (int*)malloc( 10*sizeof(int) );`\n- allocate a single integer pointer on heap\n  - `int **ppi = (int**)malloc( sizeof(int*) );`\n\n### Common malloc errors\n- mismatch between sizes\n  - `int *pi = (int*)malloc(10*sizeof(char));`\n- not casting to pointer\n  - `int i = (int)malloc(sizeof(int));`\n- forgetting `sizeof` data type\n  - `int *my_array = (int*)malloc(10);`\n\n### Realloc\n- **realloc** changes the size of memory\n  - `void *realloc(void *ptr, size_t size);`\n- heap might not contain enough space to expand at this address\n- data can be copied to a new location, changing the pointer\n  \n![realloc memory](https://i.imgur.com/9EmVRiz.png)\n\n### Important last step!\n- for every dynamically allocated section in memory, ensure to run `free` when finished using\n  - `free(void *ptr);`\n- the pointed must be to heap memory, allocated by malloc, calloc or realloc\n- signals the OS this space can now be used again\n- good practice:\n  - `ptr=NULL`\n  - immediately after `free`\n  - ensures you don't forget and mess with memory of another var\n\n# BMP images\n\n## How do cameras form images?\n- project light with a lens that has similar behaviour to our eye\n- instead of a retina, light sensitive electronics (CCD or CMOS), count arriving photons\n  - each is tuned for a colour we call RGB (red, green, blue)\n  - RGB values at one spot are called a *pixel*\n- each pixel is read off as 3 integer values\n  \n## How to sore images as a file on disk\n- an image is a 2D grid of pixels\n  - num_rows = height\n  - num_cols = width\n  - num_colors: how many per pixel could be 3 for RGB, 1 for b/w, or 4 for RGBA (alpha = transparency)\n- 2 additional types of data:\n  - a header\n    - holds information fields such as the image size, compression, color depth\n  - padding\n    - almost always present to align the elements into 4 or 8 byte boundaries (details coming)\n\n## Image file formats\n- `.bmp`: Windows bitmap\n- `.jpg`: Joint Photographic Experts Group\n- `.png`: Portable Network Graphics\n- `.tiff`: Tagged Image File Format\n- `.gif`: Graphics Interchange Format\n\n## How to read BMP file using C\n- what works well:\n  - check the magic number\n    - if it matches, very likely it follows the rules\n  - file size field: makes it easy to access all the data\n  - width and height, allows finding a specific pixel\n  - opening with code like `rb`\n- what to avoid:\n  - checking for ASCII code values: space, new line, etc.\n  - attempting to use `atoi`, `atof`\n  - if we open with `r` alone (no b), C will do some of this automatically and cause us problems\n  - `fgets`, `fscanf` meant to work with text\n\n## Word endianess\n- the order that bytes within an integer are stored in memory is a convention, named Endianess, and there is no right answer\n- most systems we deal with will be Little Endian, but there are major execptions (the Sun company)\n\n![big and little endian](https://i.imgur.com/ClJUlYd.png)\n\n### Endianess intuition helper\n- little or big?\n  - name determined by the \"significance\" of the byte at the first address:\n  - little: the least significant comes first\n  - big: the most significant comes first\n\n### Endianess and images\n- BMP files are explicitly specified to use Little Endian, which is the format of most machines (all x86 compatible)\n\n## Steganography\n- concerned with concealing the fact that a secret msg is being sent as well as concealing the msg contents\n\n![Diagram of a Steganography Software System](https://i.imgur.com/4pLrhGo.png)\n\n### Elements required for in-image steganography\n- read and write binary image data\n- read and change pixel values\n- steganography requires us to work with bits directly\n  - view the text string in binary form so we can access one bit at a time\n  - ability to modify only a single bit (the LSB) of each pixel\n  - ability to extract the LSB again for decoding\n\n## Bit-wise operations\n- shifts:\n  - `bit_arg\u003c\u003cshift_arg`\n    - shifts bits to of bit_arg shift_arg places to the left -- equivalent to multiplication by 2^shift_arg\n  - `bit_arg\u003e\u003eshift_arg`\n    − shifts bits to of bit_arg shift_arg places to the right -- equivalent to integer division by 2^shift_arg\n- bit-wise logic:\n  - left_arg \u0026 right_arg\n    − takes the bitwise AND of left_arg and right_arg\n  - left_arg | right_arg\n    - takes the bitwise OR of left_arg and right_arg\n  - left_arg ^ right_arg\n    - takes the bitwise XOR of left_arg and right_arg (one or the other but not both)\n  - ~arg\n    - takes the bitwise complement of arg\n\n### Bit-shift operators\n- moves the existing bits a specified number of positions left or right\n  - when a bit hits the edge, it is lost\n  - new bits always take 0 (for unsigned – we do not cover signed bit shifting in 206)\n- note, shifting is similar to multiplying or dividing by powers of 2\n\n### Multi-byte shifting\n- treats the true int value\n- we don't have to think about address ordering here\n- if a bit hits the boundary of its byte, it seamlessly moves to the next using significance order\n- now, only the least and most significant byte boundaries cause \"loss\"\n  \n![multi-byte shifting](https://i.imgur.com/vDbHueR.png)\n\n### Bit-wise logical operators\n- each applies a *truth table* to the bits in its args, one at a time\n- logical AND and logical OR truth tables\n- when you apply a \u0026 b, these operations are applies to all of the bits in a and b, 1 bit at a time\n\n![bit-wise logical operators](https://i.imgur.com/6tZ8Y8E.png)\n\n### Integrated bit-wise example\n- check the value of bit 3\n\n      char c = 85;\n      if( (c \u0026 (1\u003c\u003c2)) \u003e 0 )\n      printf( “bit 3 of c is a 1!\\n” );\n      else\n      printf( “bit 3 of c is a 0!\\n” );\n\n![example](https://i.imgur.com/kGDb5UQ.png)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floreina%2Fcomp206","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floreina%2Fcomp206","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floreina%2Fcomp206/lists"}