Contents


Logging into your class Linux account (Windows users)

First download and unzip an SSH Secure Shell Client such as Bitwise (which you can get from https://www.bitvise.com/ssh-client-download.)

The SSH Secure Shell Client app can be used to connect to the class Linux machine:

The SSH app can also be used to transfer files to/from the Linux box.

Logging into your class Linux account(Mac or Linux users)

Open a Terminal window and simply type
$ ssh <your UserName>@windriver.cdm.depaul.edu
(Don't type the $; it represents the command line prompt. The <your UserName> is as described in the "Windows users" section above.) For example, I would login with my user name "stu" as follows
$ ssh stu@windriver.cdm.depaul.edu
To copy a file, say "sample.txt", from your machine to a directory, say "hw1/example2/", on the Linux VM do
$ scp sample.txt <your UserName>@windriver.cdm.depaul.edu:hw1/example2/
To copy a file, say "sample.txt", from directory "hw1/example2/" on the Linux VM to the current directory of your machine, do
$ scp <your UserName>@windriver.cdm.depaul.edu:hw1/example2/sample.txt .
The period (.) refers to the current directory in Unix/Linux.

The Linux operating system

For an introductory tutorial on the Linux operating system use http://www.ee.surrey.ac.uk/Teaching/Unix/index.html or https://people.ischool.berkeley.edu/~kevin/unix-tutorial/toc.html.

We summarize below a few key commands.


To change your password

Command: passwd

Example:
$ passwd
Changing password for user stu.
Current password:
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
Note 1: Please change your password the first time you log in.

Note 2: The Linux box is for classwork only and you should not assume privacy. All files on this machine may be read by the Prof.


Display current working directory

Command: pwd

Description: Print Working Directory; i.e., display the name of the current directory.

Example:

$ pwd
/home/stu
This directory is the home directory of user stu


To list the content of a directory

Command: ls

Arguments: Optional list of files and or directory names

Options: -l

Description: Lists the specified files and or directories. For a directory, all its files and directories are listed. If no file or directory is specified, the current directory is assumed.

Example:
$ ls
$ ls .
$ ls ..aka1phoenyx  any  bar  ber  cho  dod  fin  khm  leh       luu  mun  pap  pok  ste  tro
alf          aso  bec  bol  cod  esq  gan  khz  len       mer  nag  par  qin  stu  whi
als          bak  bel  che  con  est  gra  kia  liu       mic  nun  pat  rog  ten  wil
and          ban  ben  chi  del  fah  her  kiy  lperkovi  moh  oun  pet  sid  tik  zerocool
[stu@cdmcsclpprd01 ~]$ ls -l ..
total 4
drwx------.  3 aka1phoenyx domain users   78 Dec  2  2020 aka1phoenyx
drwx------.  2 alf         alf            76 Sep  7 13:22 alf
drwx------.  2 als         als            76 Sep  7 13:22 als
drwx------.  2 and         and            76 Sep  7 13:22 and
drwx------.  2 any         any            76 Sep  7 13:22 any
drwx------.  2 aso         aso            76 Sep  7 13:22 aso
drwx------.  2 bak         bak            76 Sep  7 13:22 bak
drwx------.  2 ban         ban            76 Sep  7 13:22 ban
drwx------.  2 bar         bar            76 Sep  7 13:22 bar
drwx------.  2 bec         bec            76 Sep  7 13:22 bec
drwx------.  2 bel         bel            76 Sep  7 13:22 bel
drwx------.  2 ben         ben            76 Sep  7 13:22 ben
drwx------.  2 ber         ber            76 Sep  7 13:22 ber
drwx------.  2 bol         bol            76 Sep  7 13:22 bol
drwx------.  2 che         che            76 Sep  7 13:22 che
drwx------.  2 chi         chi            76 Sep  7 13:22 chi
drwx------.  2 cho         cho            76 Sep  7 13:22 cho
drwx------.  2 cod         cod            76 Sep  7 13:22 cod
drwx------.  2 con         con            76 Sep  7 13:22 con
drwx------.  2 del         del            76 Sep  7 13:22 del
drwx------.  2 dod         dod            76 Sep  7 13:22 dod
drwx------.  2 esq         esq            76 Sep  7 13:22 esq
drwx------.  2 est         est            76 Sep  7 13:22 est
drwx------.  2 fah         fah            76 Sep  7 13:22 fah
drwx------.  2 fin         fin            76 Sep  7 13:22 fin
drwx------.  2 gan         gan            76 Sep  7 13:22 gan
drwx------.  2 gra         gra            76 Sep  7 13:22 gra
drwx------.  2 her         her            76 Sep  7 13:22 her
drwx------.  2 khm         khm            76 Sep  7 13:22 khm
drwx------.  2 khz         khz            76 Sep  7 13:22 khz
drwx------.  2 kia         kia            76 Sep  7 13:22 kia
drwx------.  2 kiy         kiy            76 Sep  7 13:22 kiy
drwx------.  2 leh         leh            76 Sep  7 13:22 leh
drwx------.  2 len         len            76 Sep  7 13:22 len
drwx------.  2 liu         liu            76 Sep  7 13:23 liu
drwx--x--x. 14 lperkovi    domain users 4096 Sep  7 13:18 lperkovi
drwx------.  2 luu         luu            76 Sep  7 13:23 luu
drwx------.  2 mer         mer            76 Sep  7 13:23 mer
drwx------.  2 mic         mic            76 Sep  7 13:23 mic
drwx------.  2 moh         moh            76 Sep  7 13:23 moh
drwx------.  2 mun         mun            76 Sep  7 13:23 mun
drwx------.  2 nag         nag            76 Sep  7 13:23 nag
drwx------.  2 nun         nun            76 Sep  7 13:23 nun
drwx------.  2 oun         oun            76 Sep  7 13:23 oun
drwx------.  2 pap         pap            76 Sep  7 13:23 pap
drwx------.  2 par         par            76 Sep  7 13:23 par
drwx------.  2 pat         pat            76 Sep  7 13:23 pat
drwx------.  2 pet         pet            76 Sep  7 13:23 pet
drwx------.  2 pok         pok            76 Sep  7 13:23 pok
drwx------.  2 qin         qin            76 Sep  7 13:23 qin
drwx------.  2 rog         rog            76 Sep  7 13:23 rog
drwx------.  2 sid         sid            76 Sep  7 13:23 sid
drwx------.  2 ste         ste            76 Sep  7 13:23 ste
drwx------.  2 stu         stu            76 Sep  7 14:20 stu
drwx------.  2 ten         ten            76 Sep  7 13:23 ten
drwx------.  2 tik         tik            76 Sep  7 13:23 tik
drwx------.  2 tro         tro            76 Sep  7 13:23 tro
drwx------.  2 whi         whi            76 Sep  7 13:23 whi
drwx------.  2 wil         wil            76 Sep  7 13:23 wil
drwx------.  4 zerocool    domain users  104 Apr 24 18:10 zerocool

.    refers to the current directory
..  refers to the parent directory

The permissions are set so you cannot see each other's files.

Copy a file

Command: cp

Arguments:   existing_file   new_copy

Description: Copy existing_file to the file new_copy. If new_copy doesn't exist, create it. If it does exist, first delete its contents.

If new_copy is a directory, a copy of existing_file is created in directory new_copy with the same file name - existing_file.

Example:
$ cp /home/lperkovi/public/lecture1/hello.c .
$ ls
hello.c
$ ls -l
total 4
-rw-r--r--. 1 stu stu 69 Sep  1 07:00 hello.c
$ cp hello.c test.c
$ ls
hello.c test.c
$ ls -l
total 8
-rw-r--r--. 1 stu stu 69 Sep  1 07:00 hello.c
-rw-r--r--. 1 stu stu 69 Sep  1 07:00 test.c

$


Create a directory

Command: mkdir

Arguments: new_subdirectory_name

Description: Create a subdirectory of the current directory

Example:
$ mkdir hw1
$ mkdir hw2
$ ls
hello.c hw1 hw2 test.c
$ ls -l
total 8
-rw-r--r--. 1 stu stu 69 Sep  1 07:00 hello.c
drwxrwxr-x. 2 stu stu  6 Sep  1 07:01 hw1
drwxrwxr-x. 2 stu stu  6 Sep  1 07:01 hw2
-rw-r--r--. 1 stu stu 69 Sep  1 07:00 test.c

$


Delete Files/Directories

Command: rm

Arguments: file list

Options: -i -r

Description: Removes (deletes) the specified files

-i   Ask before removing each file (Good idea since it is not possible to reverse a removal)
-r Recursive remove directories and subdirectories in
the list. Files will be removed in these directories
first and then the directory itself.(Useful but dangerous)
Example:
$ rm test.c
$ ls
hello.c  hw1  hw2
$ rm hw2
rm: cannot remove `hw2': Is a directory
$ rm -r hw2
$ ls
hello.c  hw1
$ rm -ri hw1
rm: remove directory `hw1'? n
$ ls
hello.c  hw1



Rename a file/directory

Command: mv

Arguments: existing_file new_file

Options: -i

Description: Renames existing_file to have the name new_file -i Prompts if mv would overwrite an existing file.

Example:

$ mv hello.c test.c
$ ls
hw1 test.c
$ mv hw1 homeworks
$ ls
homeworks test.c


Change the current directory

Command: cd

Arguments: target_directory

Description: Change the current directory (working directory) to the specified target_directory. If no target_directory is specified, change to the login/home directory.


Example:
$ cd homeworks/
/homeworks$ pwd
/home/stu/homeworks
$ cd ..
$ ls
homeworks  test.c
$ pwd
/home/stu


Viewing a file

There are several tools available for viewing files. The most popular is more invoked as follows:

$ more test.c
#include <stdio.h>

int main()
{
  printf("hello, world\n");
}

For files larger than your console window, you will need to scroll:
To scroll the contents of a file to the screen, you can use the cat command.

Example:
$ cat test.c
#include <stdio.h>

int main()
{
printf("hello, world\n");
}
The cornmand cat gets its name from concatenate: it reads its input file names and writes them to the screen. If you give it more than one file name then cat will first concatenate (hence the name cat) the file contents one after another.

Example:
$ cat test.c test.c
#include <stdio.h>

int main()
{
   printf("hello, world\n");
}
#include <stdio.h>

int main()
{
   printf("hello, world\n");
}
Redirecting this output to a file is done using the output redirection operator >. Then:
$ cat test.c test.c > test2.txt
$ more test2.txt
#include <stdio.h>

int main()
{
  printf("hello, world\n");
}
#include <stdio.h>

int main()
{
  printf("hello, world\n");
}
would give you a file named test2.txt whose content is the contents of the concatenation of test.c and test.c. This is a good way to add files together.


Print a File

To print a file, you need to transfer the file to your PC. You can then print the file as you would any other text file on the PC.


Unix online Manual

To view the Unix online manual, you need to know the exact name of a manual topic; e.g., fork.  In some cases you may not know the exact name. You can try the man command with the -k option (for keyword)
$ man -k fork
fork (2)             - create a child process
fork (3am)           - basic process management
fork (3p)            - create a new process
forkpty (3)          - terminal utility functions
perlfork (1)         - Perl's fork() emulation
pthread_atfork (3)   - register fork handlers
pthread_atfork (3p)  - register fork handlers
Test2::IPC (3pm)     - Turn on IPC for threading or forking support.
vfork (2)            - create a child process and block parent

Once you know the name of the manual page for a topic use the man command again with that specific topic:
$ man fork
FORK(3am)                          GNU Awk Extension Modules                         FORK(3am)

NAME
       fork, wait, waitpid - basic process management

SYNOPSIS
       @load "fork"

       pid = fork()

       ret = waitpid(pid)

       ret = wait();

DESCRIPTION
       The fork extension adds three functions, as follows.

       fork() This  function  creates a new process. The return value is the zero in the child
              and the process-id number of the child in the parent, or -1 upon error.  In  the
              latter  case,  ERRNO  indicates  the problem.  In the child, PROCINFO["pid"] and
              PROCINFO["ppid"] are updated to reflect the correct values.

       waitpid()
              This function takes a numeric argument, which is the process-id to wait for. The
              return value is that of the waitpid(2) system call.

       wait() This function waits for the first child to die.  The return value is that of the
              wait(2) system call.

BUGS
       There is no corresponding exec() function.

       The interfaces could be enhanced to provide more facilities, including pulling out  the
       various bits of the return status.

 Manual page fork(3am) line 1 (press h for help or q to quit)


To move around the manual page use:
For additional info about UNIX use this Unix tutorial


Linux/Unix text editors

To edit your programs, you will need a text editor. A very basic one is nano; documentation is available at http://www.nano-editor.org/docs.php. To open a file, say 'file.txt',  for editing using nano, simply type
$ nano file.txt
nano is a basic editor that is not commonly used by Unix/Linux programmers. The two most popular editors in UNIX/Linux are vi and emacs. They are more difficult to master, however. You can learn about vi at

http://heather.cs.ucdavis.edu/~matloff/UnixAndC/Editors/ViIntro.html

and emacs at

http://ergoemacs.org/emacs/emacs.html

or

http://heather.cs.ucdavis.edu/~matloff/UnixAndC/Editors/Emacs.html

Here is a short primer on emacs. To open a file file.c using emacs, type
$ emacs file.c
Emacs will open the file called "file.c" in your current working directory or create one if no file by that name exists in your current working directory. You can start editing know. When you want to save your file, type

Ctrl-X Ctrl-S (This means pressing the Ctrl key and pressing x and then s, while still pressing the Ctrl key)

To save a file under a different name, type

Ctrl-X Ctrl-W

To exit emacs, type

Ctrl-X Ctrl-C

Here is a short list of important emacs editing commands

To move the cursor up, down, left, or right use the arrow keys.

To delete a character pointed to by the cursor, type

Ctrl-D

You can also use the Delete or Backspace keys.

To cut and paste, move the cursor to the first character of the part you want to cut and paste. Then type

Ctrl-SPACE (SPACE is the space bar)

Then move the cursor down to the last character of the part you want to cut. Then type

Ctrl-W

to cut the text. You can then move the cursor to the position where you want to paste, and type

Ctrl-Y

to paste. You can paste the cut text again and again with Ctrl-Y.

To exit the Emacs editor, type

Ctrl-X Ctrl-C.

You should be able to modify the properties of the VT102 terminal emulator in SSH to customize some of the key bindings.

For additional info about emacs go to

http://ergoemacs.org/emacs/emacs.html

or

http://heather.cs.ucdavis.edu/~matloff/UnixAndC/Editors/Emacs.html


Introduction to C

The following is a short intro to C. A good online tutorial is also available at
http://www.cprogramming.com/tutorial/c-tutorial.html


Compiling a C program and running it

To compile a single file C program in a file named hello.c use the gcc compiler.

$ cp /home/lperkovi/public/lecture1/hello.c .
$ gcc -o hello hello.c
The command gcc (GNU C Compiler) compiles the program hello.c, links it with any standard c library routines called (e.g. i/o routines) and produces the executable file named hello.

The file hello is an executable and could run at the command line

$ hello
if the PATH environment variable includes the current directory (denoted .) . The value of the PATH environment variable is a sequence of directories the shell will look in for executables. To view this sequence, do:
$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/stu/.local/bin:/home/stu/bin
Note the the current directory (.) is not included. To execute hello, you will need to specify where the executable hello is:
$ ./hello
hello, world
$ /home/stu/hello
hello, world
/home/stu/hello is the absolute pathname of file hello
./hello is the relative pathname of file hello, and it is relative to (current working) directory /home/stu


From source to executable

hello.c is compiled as follows:
$ gcc -o hello hello.c
The compilation system performs the translation of the source file hello.c to an executable hello which consists of a sequence of low-level machine language instructions.

To obtain the "preprocessed" source program hello.i, do:
$ gcc -E hello.c
To obtain the assembly program hello.s, do:
$ gcc -S hello.c
$ ls
hello  hello.c  hello.s
$ more hello.s
    .file    "hello.c"
    .text
    .section    .rodata
.LC0:
    .string    "hello, world"
    .text
    .globl    main
    .type    main, @function
main:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %edi
    call    puts
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size    main, .-main
    .ident    "GCC: (GNU) 8.4.1 20200928 (Red Hat 8.4.1-1.0.1)"
    .section    .note.GNU-stack,"",@progbits
To obtain the relocatable object file (binary file that is not yet executable because it is not linked to helper library functions) hello.o, do:
$ gcc -c hello.c
$ ls
hello  hello.c  hello.o  hello.s
$ more hello.o

******** hello.o: Not a text file ********
A binary file cannot be viewed using text viewing tools...


First C program

We already saw the classical first program:
hello.c
You can get the examples that follow by copying folder lecture1 to your current directory:

$ cp -r ../lperkovi/public/lecture1 .
$ ls
hello  hello.c  hello.o hello.s  lecture1
$ cd lecture1
$ ls
arithmetic.c  count.c            loops.c             pointers5.c  struct3.c
array2D.c     data-types.c       malloc_example0.c   pointers6.c  struct.c
arrays.c      demo1.c            malloc_example1A.c  pointers7.c  sum.c
ascii.c       fileIO_example1.c  malloc_example1.c   pointers.c   temp.c
blocks.c      fileIO_example2.c  malloc_example2.c   power.c      terminal.c
cmdline0.c    flow.c             pointers2.c         sort.c       test.txt
cmdline1.c    getopt_example.c   pointers3.c         str.c
count2.c      hello.c            pointers4.c         struct2.c



The basics of a C program

Consider
demo1.c
The #include line at the top are similar to an import in Java or Python but they differ significantly. In C, the #include is a pre-compilation directive that instructs the compiler to replace the #include line with the text from the indicated file. This file is called a header file and it contains references to library function executables that the program uses.

The main function has some similarity to Java also in that just like a Java program, a C program must have exactly one main function (now that we are in C, we refer to methods as functions from now on). (The Python equivalent to main is the top-level code in a module, i.e. code that is not inside a function or class definition.) The main function can be prototyped to return other types, but void and int are the most common. For this course we will adhere to the most common practice which is to return an int. The usefulness of this returned value is however moot for our purposes since we do no script programming which might examine and use the value returned by main.

Variable declarations are similar to Java. However in C, the compiler makes no initializations as in Java. Newly declared variables contain garbage values. An int is a 32 bit signed value having a range of about negative 2G to positive 2G (1G = 230). An unsigned int is a strictly positive 32 bit value ranging from 0 to 4G. C has floating point types float and double. It is common practice in C (as in Java) to just use the double type with its increased precision for floating point numbers to minimize accumulated rounding errors. The char type is an 8 bit signed quantity that stores the ascii code for a character. Thus a char is just an 8 bit int and has an unsigned version also. We will discuss data types some more later.

Console I/O can be done via the many print, scan and get functions (see the man pages).

Our first C program uses:
	printf("Please enter an integer: ");
and
printf("x: %d y: %d\n", x,y );
In the first printf we supply a string literal. What you see is what you get. In the second printf call we pass in a format string, followed by one or more arguments ( the x and y variables). The format string is printed as is except for placeholders denoted with a % symbols. The values of the arguments (x and y) will be printed exactly where the placeholders are. Each placeholder (%) is followed by a conversion instruction---d in our examples---that says how the value is to be printed (in decimal notation, or binary, hexadecimal, etc.) In ou case, %d means decimal notation. At the end of the format there is an escape sequence \n which denotes a newline.

To read data from the keyboard our first C program uses:

	scanf("%d", &x );	
The first argument is, again, a format string. It is used to instruct the function scanf how to interpret what the user types. In this case it instructs scanf to interpret the user's input as an integer in decimal notation. The second argument contains the name of the variable where the input is to be stored (x). Note the ampersand character ( & ) before the x variable. This ampersand character is the address-of operator. This operator when placed before an variable produces the address of that variable, rather than the value of the variable. This address value is a positive memory address between 0 and however much memory you have in your computer. scanf needs the address of x not the value of x because scanf wants to know where to store the numeric conversion of the string you typed into the keyboard.

Recall that when we just want the value of x we just use the name x in a statement such as:

	x=15;  // assignment into the value of x
or
y=x+5; // lookup the value of x
or
printf("value of x: %d", x ); // lookup the value of x

This is the first time we have ever been concerned with the address of where a variable is stored in memory. Java intentionally shields us from any such concerns. C does not. Thus it is important to understand the distinction between the value of a variable, and the address of a variable. They are not the same. If we want the address we must put the & operator immediately to the left of the variable name.


Basic data types

The four basic data types are int, float, double, and char.

data-types.c

In
 printf("%d %c\n",x,a);
 printf("%3d %5c\n",x,a);
 printf("%f %e\n",e,d);
 printf("%.9f %.9e\n",e,d);
 printf("%20.9f %20.9e\n",e,d);

conversion instructions other than d are used. Here are the conversions we will use:

Conversion Specification Output
%c character
%s string of characters
%d or %i decimal integer
%e floating point number in e-notation
%f floating point number in decimal notation
%p pointer
%u unsigned decimal integer
%o octal integer
%x hexadecimal integer, using lower case
%X hexadecimal integer, using upper case
%% Prints a % sign

A number right after the placeholder (%) specifies the width (i.e., the number of characters) that the value should occupy, with blank spaces used as fillers when necessary:
printf("%3d %5c\n",x,a);
printf("%20.9f %20.9e\n",e,d);
For float and double values, a precision can be specified:
printf("%.9f %.9e\n",e,d);
printf("%20.9f %20.9e\n",e,d);
The following is a list of some common escape sequences: 

Escape Sequences Meaning
\n New break
\b Backspace
\f Form feed
\r Carriage return
\t Horizontal tab
\\ Prints a \
\' prints a '
\" prints a "

To learn more about printf, we use the man page
$ man -k printf
asprintf (3)         - print to allocated string
dprintf (3)          - formatted output conversion
dprintf (3p)         - print formatted output
fprintf (3)          - formatted output conversion
fprintf (3p)         - print formatted output
fwprintf (3)         - formatted wide-character output conversion
fwprintf (3p)        - print formatted wide-character output
printf (1)           - format and print data
printf (1p)          - write formatted output
printf (3)           - formatted output conversion
printf (3p)          - print formatted output
snprintf (3)         - formatted output conversion
snprintf (3p)        - print formatted output
sprintf (3)          - formatted output conversion
sprintf (3p)         - print formatted output
swprintf (3)         - formatted wide-character output conversion
swprintf (3p)        - print formatted wide-character output
vasprintf (3)        - print to allocated string
vdprintf (3)         - formatted output conversion
vfprintf (3p)        - format output of a stdarg argument list
vfprintf (3)         - formatted output conversion
vfwprintf (3)        - formatted wide-character output conversion
vfwprintf (3p)       - wide-character formatted output of a stdarg argument list
vprintf (3)          - formatted output conversion
vprintf (3p)         - format the output of a stdarg argument list
vsnprintf (3)        - formatted output conversion
vsnprintf (3p)       - format output of a stdarg argument list
vsprintf (3)         - formatted output conversion
vswprintf (3)        - formatted wide-character output conversion
vswprintf (3p)       - wide-character formatted output of a stdarg argument list
vwprintf (3)         - formatted wide-character output conversion
vwprintf (3p)        - wide-character formatted output of a stdarg argument list
wprintf (3)          - formatted wide-character output conversion
wprintf (3p)         - print formatted wide-character output
The printf C function is described in man 3:
$ man 3 printf
PRINTF(3)                  Linux Programmer's Manual                 PRINTF(3)

NAME
       printf,   fprintf,  sprintf,  snprintf,  vprintf,  vfprintf,  vsprintf,
       vsnprintf - formatted output conversion

SYNOPSIS
       #include <stdio.h>

       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
       int sprintf(char *str, const char *format, ...);
       int snprintf(char *str, size_t size, const char *format, ...);

       #include <stdarg.h>

       int vprintf(const char *format, va_list ap);
       int vfprintf(FILE *stream, const char *format, va_list ap);
       int vsprintf(char *str, const char *format, va_list ap);
       int vsnprintf(char *str, size_t size, const char *format, va_list ap);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       snprintf(), vsnprintf(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 ||
       _ISOC99_SOURCE; or cc -std=c99
 Manual page printf(3) line 1
...
In C, the char type is really an integer type. We use the conversion instructions to illustrate this:
ascii.c

Algebraic operations

C supports classical algebraic operators.

arithmetic.c

Notes:
/ is the integer division operator when the numerator and denominator are integers.
% is the modulus (remainder) operator.


Loops

There are three types of loops in C:
loops.c
Some more examples
sum.c
temp.c
Note the use the #define line to define symbolic constants LOWER, UPPER, andS STEP. It is good practice to use them instead of "burying" numbers like 300 and 20 deep inside the code. Symbolic constants can refer to values of any type (int, char, string, float, etc.)

The command #define STEP 20 causes any occurence of the word STEP in your source file to be replaced by 12 by the preprocessor. Note also the use of the function-like macro ftoc; the code fragment (5.0/9.0)*((fahr)-32)will be used to substitute every occurence of ftoc(fahr)in the source code..

Conditionals

The usual if-else statement is the conditional statement in C.
blocks.c
Note that the conditional expression must be in parentheses. Compound conditional expressions are created using || (or), && (and), and ! (not).
terminal.c

Flow Control

C supports two statements that modify the execution of a loop:

flow.c

Functions

Functions in C are defined as expected:
power.c
Parameter passing: In C, function arguments are passed "by value". This means that the called function is given copies of the original values. For example, when the main program executes power(2, i) when the value of i is 5, copies of 2 and 5 are written to local variables base and n (they are local to the execution of function power):
int power(int base, int n)
{
  int i, p;
  p = 1;
  for (i = 1; i <= n; ++i)
    p = p * base;
  return p;
}

C pointers

We aleady saw that the & operator is used to obtain the (memory) address of a variable:
  scanf("%d", &x );
Since a C programmer may need to store a variable's address for later use, C provides a data type called the pointer type. The pointer type allows us to declare variables that are meant to hold the address of some other variable. So, a pointer is a variable that contains the address of another variable.

Declaring a pointer variable is done as follows:
	int *pi   /* creates a 64 bit variable whose data type is pointer to int */
int i; /* an int var */
pi = &i; /* pi now holds i's address - i.e it points to i */
pointers.c
Every variable in C has 2 at least 2 properties:
A pointer variable is itself a variable and its value can change. A pointer can hold only one of 3 values:
Pointer variables are NOT the data type of the variable they point to. The data type of pi (above) is pointer to int NOT INT. The name of the pointer variable is pi    NOT *pi .

You can declare a pointer to ANY data type.
char *pc;   /* pc is type: pointer to char */
float *pf; /* pf is type: pointer to float */
double *pd; /* pd is type: pointer to double */

typedef struct
double cost;
int age;
} student_type;

student_type *ps; /* ps can store the address of any student_type variable */

student_type one_student;
ps = &one_student; /* ps has the address where one_student is stored in memory */


Dereferencing pointer variables

Let's go back to our int example:
int *pi;  /* variable of type pointer to int  */
int i; /* plain old int var */
pi = &i; /* pi now contains address of var i */
We can use pointer variable pi to manipulate the contents of the int variable i. To do so we must dereference pi as follows:
*pi = 15; /* i now contains 15. */
printf(" value pointed to by pi is: %d\n" *pi ); /* deref's pi and prints 15 */
The expression *pi can be thought of as   the value at the address which is stored in pi.

Using pi with the * in front of it is called dereferencing the pointer variable.

In summary, when pi is defined as:
int *pi;


C pointers as function arguments

In C arguments to functions are passed by value.
pointers2.c
So, does the below function swap work correctly?
void swap(int x, int y)
{
  int temp;

  temp = x;
  x = y;
  y = temp;
}

int main()
{
  int a = 0;
  int b = -123;
  swap(a, b);
  return 0;
}

pointers3.c
To alter the value of a variable (e.g., val in example pointers2 and a and b in example pointers3) in the calling function (i.e., function main), the calling function must pass a pointer to the variable.
pointers4.c
The correct way to swap in C:
pointers5.c


C arrays and strings

Arrays store a set of "indexable" values of the same type.
arrays.c
For an arrays with n entries, the valid index values are from 0 to n-1.

A C string is a special kind of array of characters: the string ends with character '\0', the NULL character which is not necessarily the last character of the array.
str.c
Notes:


C pointer arithmetic

Pointers can be incremented:
int y;
int *p = &y;
p = p + 5;
Pointer p is incremented by 5*4 = 20 bytes. This is because p is an integer pointer and what p + 5 really means is the 5th integer after the one that p references.

Example: pointers6.c


C pointers and arrays

Anything you can do with arrays, you can do with pointers (faster!) More precisely:
After executing this code fragment
int a[10];
int *p;
p = a;
element a[0] can be accessed as *pa, or *a, or p[0]
element a[1] can be accessed as *(pa+1), or *(a+1), or p[1]
element a[2] can be accessed as *(pa+2), or *(a+1), or p[2]
etc.

The same is true if a (respectively, p) was an array of (respectively, a pointer to) chars, doubles, etc

In fact, C compiles a[i] to *(a+i)

Example: pointers7.c


Arrays as function arguments

Example: sort.c


Structures

A structure is a grouping of several variables, possibly of different type, under a single name.
struct.c
The typedef instruction, which defines a new (user-defined) type, can be used to facilitate the usage of structs:
struct2.c


Structures and pointers

If e is defined as a pointer to an employee structure
employee *eptr;
then the pointer must be dereferenced in order for the structure content to be accessed:

(*eptr).first = "Sam";
(*eptr).last = "Smith";
(*eptr).age = 55;

printf("%s %s, age %d\n", (*eptr).first, (*eptr).last, (*eptr).age);
An alternative notation is typically used:
// alternative notation                                                      
eptr->first = "Sam";
eptr->last = "Smith";
eptr->age = 55;

printf("%s %s, age %d\n", eptr->first, eptr->last, eptr->age);
struct3.c
Note: the call malloc(12) allocates 12 bytes and returns the addess of the first byte (similar to new() in C++ and Java)


Function malloc()

Function malloc() is C's version of the new operator you have seen in Java or C++ programs. Operator new is used to create a new object dynamically, i.e. at run time, i.e. while the program executes. What that means is the space in memory is allocated to store the object's instance variables.

C is not object-oriented and does not have objects. It does however support dynamically allocated memory using the malloc() function. Function malloc() takes a input a number n and allocates n consecutive bytes in memory; it return a pointer to the first of the n bytes. The signature of malloc is
void* malloc(int n)
Note that the input is an integer and the return type is a generic address: void*. When you need to dynamically create a new integer, for example, you will use malloc() to allocate 4 bytes. However, in order to use these 4 bytes as an int value, you will need to cast the void* pointer as an int* pointer. Therefore, the typical usage of malloc() to "create" an integer dynamically is:
int *iptr = (int *) malloc(4);
Then you can assign an integer value to this new, dynamically allocated integer:
*iptr = 5
To dynamically create an array of 10 integers you would need 40 bytes:
int *array = (int *) malloc(40)
Even better, for code portability reasons, would be using the C sizeof() function that takes a type and returns the number of bytes the type requires:
int *array = (int *) malloc(10*sizeof(int))
Then you can use array just like a statically defined array:
for (int i = 0; i < 10; i++)
  array[i] = i;
    malloc_example0.c

At the end of the above program the code
free(array);
gives back the dynamically allocated memory space pointed to by array to the operating system. This freeing of memory must be done when the dynamically allocated memory space is no longer needed by the program. Failure to do so may lead to a "memory leak" and, eventually, no more memory being available for dynamic memory allocation. (We will go much deeper into this subject in weeks 5-6.)


Two-dimensional arrays

A program that uses a statically defined 2D array:

    array2D.c


Two-dimensional dynamically allocated arrays

There are two ways to create dynamically allocated 2D arrays. The first is to simply use a 1D array.

    malloc_example1A.c

This approach requires a function that maps row index i and column index j to the appropriate index of the 1D array.

Another approach is to create a multi-level array. To do this, it is helpful and cleaner to use the C typedef instruction to define new types for a table row and for the table itself:
typedef int* row_t;
typedef row_t* table_t;
The new type row_t is just a new name for the int* type; As we saw above, it can be used to refer to a dynamically allocated array of integers, i.e. a row of a 2-D array of integers.

The new type table_t is defined as row_t* and can thus be used to refer to a dynamically allocated array of row_t entries. In other words, a table_t variable will refer to an array of integer arrays, i.e. a 2-D array of integers.

Here is the complete program that creates a 2x3 array of integers dynamically and initializes all its values to 0:

    malloc_example1.c

Another example illustrating how to dynamically create a 2-D array of structs:

    malloc_example2.c

In both cases, note how the dynamically allocated memory is freed when it is no longer needed.


File Input/Output and parsing strings

To open a text file test.txt for reading do:
FILE* fp = fopen("test.txt", "r");
Then, to read the first line of the file into a character array buf, use function fgets():
fgets(buf, 1000, fp)
Functions fgets() will read a line or the first 999 bytes if the line is 1000+ bytes long) from the file refered to by fp and store it into the character array buf. The following is a complete program that opens file test.txt, reads it line by line, prints each line to standard output, and then closes the file:

    fileIO_example1.c

When executed on file test.txt, it will show on the screen the content of file test.txt:
$ ./fileIO_example1
a 100,:,11
 b 200,:,22
c 300,:,33
 d 400,:,44
e 500,:,55
Suppose now that you want to parse the lines in the above test.txt file that start with a blank space in order to extract the first character and the two integers. For example, you would like to extract b, 200 and 22 from line
 b 200,:,22
and store them, respectively, in variables, c, a, and b defined as:
  char c;
  unsigned int a;
  int b;
The function sscanf() can be used to do this. It takes as input: the character array buf that contains the line, a format string, and addresses of variables c, a, and b:
sscanf(buf, " %c %u,:,%d", &c, &a, &b);
The format string describes the format of the string stored in buf and the placeholders %c, %u, and %u indicate the places where the values to be extracted into c, a, and b are.

    fileIO_example2.c


Command line arguments

Programs sometimes take command line input arguments:
$ ./cmdline0 Ljubomir
Hello, Ljubomir!
$ ./cmdline0 Ellie
Hello, Ellie!
$ ./cmdline0
Hello, World!
    cmdline0.c

If you want your C program to handle any command line input, you need to define function main() like this:
int main(int argc, char* argv[])
The argument argc will be assigned the number of (blank separated) command line arguments when the program is executed; this includes the name of the executable (./cmdline0 in the above examples).  The argument argv is an array of strings that will contain all the command line arguments. For example, in
$ ./cmdline0 Ljubomir
Hello, Ljubomir!
the argc is will be 2, argv[0] will be string "./cmdline0" and argv[1] will be "Ljubomir".

The following example uses a program (cmdline1.c) thar prints the values of argc and of every every string in array argv:
$ ./cmdline1 how many arguments?
4 arguments
 0: ./cmdline1
 1: how
 2: many
 3: arguments?
    cmdline1.c


Function getopt()

Function getopt() is used to process Unix-like command line options of the type -x such as the -l option of the ls (list directory) instruction. Here is some sample usage of a program getopt_example.c that can take 4 command line options a, b, c, and d. Option a takes an integer argument, option b takes a string argument and options c and d take no argument (they are simply flags):
$ ./getopt_example                      
a = 0, b = (null), flagc = 0, flagd = 0     // all options receive default values
$ ./getopt_example -a 3
a = 3, b = (null), flagc = 0, flagd = 0     // option a is 3
$ ./getopt_example -a 3 -b hello!
a = 3, b = hello!, flagc = 0, flagd = 0     // a is 3 and b is string "hello!"
$ ./getopt_example -a 3 -b hello! -c
a = 3, b = hello!, flagc = 1, flagd = 0     // flag c is set as well
$ ./getopt_example -a 3 -b hello! -d
a = 3, b = hello!, flagc = 0, flagd = 1     // example with flag d instead
$ ./getopt_example -b hello! -d
a = 0, b = hello!, flagc = 0, flagd = 1     // using b and d options only
$ ./getopt_example -e
./getopt_example: invalid option -- 'e'     // an invalid option
ERROR!
    getopt_example.c

The last argument of function getopt in the above program is "a:b:cd": that is the option string that contains the legitimate option characters. Any character followed by a colon (:) is an option that takes an argument.

By repeatedly calling getopt() in a while loop as shown above, we can retrieve the command line options one by one. Any option that takes an argument can access this argument through the global variable optarg defined in the getopt.c library.


Extracting the set index and tag from an address

In order to extract the set index and the tag from a memory address stored in (unsigned long long int) variable address, you need to define a "mask" and then use C logical operators & (logical and) and >> (logical right shift).

Assume that variables s and b contain the number of set index and byte offset bits in a memory address. First you create the mask which is an integer that contains, in its low order bits, s ones:
unsigned long long int mask = (pow(2, s) - 1);
Then the set index is obtained as follows:
unsigned long long int set_index = (address >> b) & mask;
and the tag is obtained as follows:
unsigned long long int tag = address >> (s+b);