Contents


Logging into your class Linux account

First obtain and unzip the SSH Secure Shell Client at

http://my.cdm.depaul.edu/resources/software/SSHSecureShellClient-3.2.9.zip

The SSH Secure Shell Client app can be used to connect to the class Linux machine:
***Some of you will need to use the first 4 or  5 letters of your last name. Try first 3, then 4, and then 5***



Intro to UNIX/Linux



To change your password

Command: passwd

Example:
stu@riely373:~$ passwd
Changing password for stu.
(current) UNIX password:
Enter new UNIX password:
Retype new UNIX password:
Note: The Linux box is for classwork only. 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:

stu@riely373:~$ 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:
stu@riely373:~$ ls
stu@riely373:~$ ls .
stu@riely373:~$ ls ..
alg  bia   che  dav  fen   hei  kur  mei  nys   sal  she  tra
alz  bro   chi  dem  ghan  hes  liu  mil  pan   sch  stu  van
any  cham  cho  elm  ghar  jiw  mac  mon  prof  sci  tay  wil
ath  chan  dan  fai  gie   kru  mcc  nak  rob   sha  tho
stu@riely373:~$ ls -l ..
total 188
drwx------  2 alg  alg  4096 2013-09-16 10:53 alg
drwx------  2 alz  alz  4096 2013-09-16 10:53 alz
drwx------  2 any  any  4096 2013-09-16 10:53 any
drwx------  2 ath  ath  4096 2013-09-16 10:53 ath
drwx------  2 bia  bia  4096 2013-09-16 10:53 bia
drwx------  2 bro  bro  4096 2013-09-16 10:53 bro
drwx------  2 cham cham 4096 2013-09-16 10:53 cham
drwx------  2 chan chan 4096 2013-09-16 10:53 chan
drwx------  2 che  che  4096 2013-09-16 10:53 che
drwx------  2 chi  chi  4096 2013-09-16 10:53 chi
drwx------  2 cho  cho  4096 2013-09-16 10:53 cho
drwx------  2 dan  dan  4096 2013-09-16 10:53 dan
drwx------  2 dav  dav  4096 2013-09-16 10:53 dav
drwx------  2 dem  dem  4096 2013-09-16 10:53 dem
drwx------  2 elm  elm  4096 2013-09-16 10:53 elm
drwx------  2 fai  fai  4096 2013-09-16 10:53 fai
drwx------  2 fen  fen  4096 2013-09-16 10:53 fen
drwx------  2 ghan ghan 4096 2013-09-16 10:53 ghan
drwx------  2 ghar ghar 4096 2013-09-16 10:53 ghar
drwx------  2 gie  gie  4096 2013-09-16 10:53 gie
drwx------  2 hei  hei  4096 2013-09-16 10:53 hei
drwx------  2 hes  hes  4096 2013-09-16 10:53 hes
drwx------  2 jiw  jiw  4096 2013-09-16 10:53 jiw
drwx------  2 kru  kru  4096 2013-09-16 10:53 kru
drwx------  2 kur  kur  4096 2013-09-16 10:53 kur
drwx------  2 liu  liu  4096 2013-09-16 10:53 liu
drwx------  2 mac  mac  4096 2013-09-16 10:53 mac
drwx------  2 mcc  mcc  4096 2013-09-16 10:53 mcc
drwx------  2 mei  mei  4096 2013-09-16 10:53 mei
drwx------  2 mil  mil  4096 2013-09-16 10:53 mil
drwx------  2 mon  mon  4096 2013-09-16 10:53 mon
drwx------  2 nak  nak  4096 2013-09-16 10:53 nak
drwx------  2 nys  nys  4096 2013-09-16 10:53 nys
drwx------  2 pan  pan  4096 2013-09-16 10:53 pan
drwx--x--x 13 prof prof 4096 2013-09-16 10:52 prof
drwx------  2 rob  rob  4096 2013-09-16 10:53 rob
drwx------  2 sal  sal  4096 2013-09-16 10:53 sal
drwx------  2 sch  sch  4096 2013-09-16 10:53 sch
drwx------  2 sci  sci  4096 2013-09-16 10:53 sci
drwx------  2 sha  sha  4096 2013-09-16 10:53 sha
drwx------  2 she  she  4096 2013-09-16 10:53 she
drwx------  3 stu  stu  4096 2013-09-16 10:53 stu
drwx------  2 tay  tay  4096 2013-09-16 10:53 tay
drwx------  2 tho  tho  4096 2013-09-16 10:53 tho
drwx------  2 tra  tra  4096 2013-09-16 10:53 tra
drwx------  2 van  van  4096 2013-09-16 10:53 van
drwx------  2 wil  wil  4096 2013-09-16 10:53 wil
stu@riely373:~$

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

The permissions are set so you cannot see each other's files. You may all view stu's files, where I will do class examples.

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:
stu@riely373:~$ cp /home/prof/public/lecture1/hello.c .
stu@riely373:~$ ls
hello.c
stu@riely373:~$ ls -l
total 4
-rw-r--r-- 1 stu stu 70 2013-01-07 09:47 hello.c
stu@riely373:~$ cp hello.c test.c
stu@riely373:~$ ls
hello.c test.c
stu@riely373:~$ ls -l
total 8
-rw-r--r-- 1 stu stu 70 2013-01-07 09:47 hello.c
-rw-r--r-- 1 stu stu 70 2013-01-07 09:53 test.c
stu@riely373:~$


Create a directory

Command: mkdir

Arguments: new_subdirectory_name

Description: Create a subdirectory of the current directory

Example:
stu@riely373:~$ mkdir hw1
stu@riely373:~$ mkdir hw2
stu@riely373:~$ ls
hello.c hw1 hw2 test.c
stu@riely373:~$ ls -l
total 16
-rw-r--r-- 1 stu stu 70 2013-01-07 09:47 hello.c
drwxr-xr-x 2 stu stu 4096 2013-01-07 10:00 hw1
drwxr-xr-x 2 stu stu 4096 2013-01-07 10:00 hw2
-rw-r--r-- 1 stu stu 70 2013-01-07 09:59 test.c
stu@riely373:~$


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:
stu@riely373:~$ rm test.c
stu@riely373:~$ ls
hello.c  hw1  hw2
stu@riely373:~$ rm hw2
rm: cannot remove `hw2': Is a directory
stu@riely373:~$ rm -r hw2
stu@riely373:~$ ls
hello.c  hw1
stu@riely373:~$ rm -ri hw1
rm: remove directory `hw1'? n
stu@riely373:~$ ls
hello.c  hw1
stu@riely373:~$



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:

stu@riely373:~$ mv hello.c test.c
stu@riely373:~$ ls
hw1 test.c
stu@riely373:~$ mv hw1 homeworks
stu@riely373:~$ ls
homeworks test.c
stu@riely373:~$


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:
stu@riely373:~$ cd homeworks/
stu@riely373:~/homeworks$ pwd
/home/stu/homeworks
stu@riely373:~/homeworks$ cd ..
stu@riely373:~$ ls
homeworks  test.c
stu@riely373:~$ pwd
/home/stu
stu@riely373:~$


Viewing a file

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

stu@riely373:~$ more test.c
#include <stdio.h>

int main()
{
  printf("hello, world\n");
}
stu@riely373:~$

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:
stu@riely373:~$ cat test.c
#include <stdio.h>

int main()
{
printf("hello, world\n");
}
stu@riely373:~$
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 the file contents one after another.

Example:
stu@riely373:~$ cat test.c test.c
#include <stdio.h>

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

int main()
{
   printf("hello, world\n");
}
stu@riely373:~$

Redirecting this output to a file
stu@riely373:~$ cat test.c test.c > test2.txt
stu@riely373:~$ more test2.txt
#include <stdio.h>

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

int main()
{
  printf("hello, world\n");
}
stu@riely373:~$
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 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)
stu@riely373:~$ man -k fork
fork (2) - create a child process
forkpty (3) - tty utility functions
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:
stu@riely373:~$ man fork
FORK(2)                    Linux Programmer's Manual                   FORK(2)

NAME
       fork - create a child process

SYNOPSIS
       #include <unistd.h>

       pid_t fork(void);

DESCRIPTION
       fork()  creates  a new process by duplicating the calling process.  The
       new process, referred to as the child, is an  exact  duplicate  of  the
       calling  process,  referred  to as the parent, except for the following
       points:

       *  The child has its own unique process ID, and this PID does not match
          the ID of any existing process group (setpgid(2)).

       *  The  child's  parent  process ID is the same as the parent's process
          ID.

       *  The child does not inherit  its  parent's  memory  locks  (mlock(2),
          mlockall(2)).

 Manual page fork(2) line 1

To move around the manual page use:
For additional info about UNIX go to Norman Matloff's intro to Unix



Overview of UNIX/Linux editors




Text editor

To edit your programs, you will need a text editor. The two most popular editors in UNIX/Linux are vi and emacs. You can learn about vi at

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

and emacs at

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

Here is a short primer on emacs. To start emacs type

$ emacs

To open a file file.c using emacs, type

$ emacs file.c

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 if you change the SSH Secure Shell Client settings (under Edit -> Settings -> Keyboard)

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 Norman Matloff's intro to Unix



Intro to C




Compiling a C program and running it

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

stu@riely373:~$ cp /home/prof/public/lecture1/hello.c .
stu@riely373:~$ 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

stu@riely373:~$ 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:
stu@riely373:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Note the the current directory (.) is not included. To execute hello, you will need to specify where the executable hello is:
stu@riely373:~$ ./hello
hello, world
stu@riely373:~$ /home/stu/hello
hello, world
stu@riely373:~$
/home/stu/hello is the absolute pathname of file hello
./hello is the relative pathname of file hello, and it is relative to 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:
stu@riely373:~$ gcc -S hello.c
stu@riely373:~$ ls
hello  hello.c  hello.s
stu@riely373:~$ more hello.s
        .file   "hello.c"
        .section        .rodata
.LC0:
        .string "hello, world"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        andl    $-16, %esp
        subl    $16, %esp
        movl    $.LC0, (%esp)
        call    puts
        leave
        ret
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
        .section        .note.GNU-stack,"",@progbits
stu@riely373:~$
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:

stu@riely373:~$ gcc -c hello.c
stu@riely373:~$ ls
hello  hello.c  hello.o  hello.s
stu@riely373:~$ 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:

stu@riely373:~$ cp -r ../prof/public/lecture1 .
stu@riely373:~$ ls
hello  hello.c  hello.o hello.s  lecture1
stu@riely373:~$ cd lecture1
stu@riely373:~/lecture1$ ls
arithmetic.c  count2.c      flow.c       pointers3.c  power.c
ascii.c       count.c       hello.c      pointers4.c  sort.c
blocks.c      data-types.c  loops.c      pointers5.c  sum.c
cmdline.c     demo1.c       pointers2.c  pointers.c   temp.c

stu@riely373:~/lecture1$


The basics of a C program

Consider
demo1.c
The #include line at the top are similar to an import in Java 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 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
stu@riely373:~$ man -k printf
asprintf (3)         - print to allocated string
dprintf (3)          - print to a file descriptor
fprintf (3)          - formatted output conversion
fwprintf (3)         - formatted wide-character output conversion
printf (1)           - format and print data
printf (3)           - formatted output conversion
snprintf (3)         - formatted output conversion
sprintf (3)          - formatted output conversion
swprintf (3)         - formatted wide-character output conversion
vasprintf (3)        - print to allocated string
vdprintf (3)         - print to a file descriptor
vfprintf (3)         - formatted output conversion
vfwprintf (3)        - formatted wide-character output conversion
vprintf (3)          - formatted output conversion
vsnprintf (3)        - formatted output conversion
vsprintf (3)         - formatted output conversion
vswprintf (3)        - formatted wide-character output conversion
vwprintf (3)         - formatted wide-character output conversion
wprintf (3)          - formatted wide-character output conversion
The printf C function is described in man 3:
stu@riely373:~$ 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 and 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.)

Conditionals

The usual if-else statement is the conditional statement in C.
blocks.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 32 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;
To create a 2-dimensional array of integers dynamically, 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 integer

The new type table_t is defined as row_t* and can thus be used to refer to a dynamically allocates 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 integer.

Here is the complete program that creates a 2x3 array of integers dynamically and initializes all its values to 0:
#include <stdlib.h>
#include <stdio.h>

typedef int* row_t;       // define row type                                   
typedef row_t* table_t;   // define table type                                 

int main () {

  int num_rows = 2;
  int num_columns = 3;
  table_t t;

  int i,j;

  // allocate space for holding num_rows row references                        
  // t will refer to this spaces                                               
  t = (table_t) malloc(sizeof(row_t) * num_rows);


  for (i=0; i<num_rows; i++)
    // for every row allocate space for num_columns integers                    
    t[i]=(int *) malloc(sizeof(int) * num_columns);

  // Fill table t with zeros                                                   
  for (i=0; i<num_rows; i++)
    for (j=0; j<num_columns; j++)
      t[i][j] = 0;

  // Print the value in table t, row by row                                    
  for (i=0; i<num_rows; i++){
    for (j=0; j<num_columns; j++)
      printf("%d ", t[i][j]);
    printf("\n");
  }

  return 0;
}
You can find this program, malloc_example2.c, in directory /home/prof/public/lecture1/ of our linux box riely373.cdm.depaul.edu. You can find there another example, malloc_example.c, that allocates a 2-D array of structs containing a memory address and an integer.


File Input/Output and parsing strings

To open a text file "text.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 ccomplete program that opens file "test.txt", reads it line by line, prints each line to standard output, and then closes the file:
#include <stdio.h>   // to use printf, FILE, fgets, fclose                     

int main()
{
  char buf[1000];    // an array of characters for storing a line              

  FILE* fp = fopen("test.txt", "r");  // open file                             

  while( fgets(buf, 1000, fp) != NULL) {
    // repeatedly read a file line into buf until end of file                  
    // and print content of buf (i.e. the line)                                
    printf("%s\n", buf);
  }

  fclose(fp);          // close the file                                         

  return 0;
}
When executed, 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
The complete fileIO_example1.c program and the test file test.txt are in directory /home/prof/public/lecture1/ of our linux box.

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.

The complete fileIO_example2.c program that parses the lines of file test.txt is in directory /home/prof/public/lecture1/.