This lecture provides a general overview of the three languages we will be studying this term. A very short example of each program language is provided and details regarding how to compile and execute the programs on a Linux system are provided. You can write your programs/scripts using any editor (e.g. vi, emacs, kate etc.)
The following Java program, with which you should be familiar, displays
the text Hello world!
on the display:
/* Source file Hello.java */
public class Hello {
public static void main(String [] args) {
System.out.println("Hello world!");
}
}
Hello.java
Compiling and executing the program is a two-phase process. We must first compile the program to bytecode, then run the resulting bytecode in a Java interpreter:
$ javac Hello.java $ java Hello Hello World! $
Note that the $
is a generic Unix prompt. The bold
text is what you enter, the non-bold text is generated by the operating
system/shell.
Here is a simple C program that, when compiled and executed also displays the string Hello world! on the screen:
/* Source file hello1.c */
#include <stdio.h>
int
main()
{
printf("Hello world!\n");
return 0;
}
hello1.c
The source consists of a header file stdio.h
which
is textually included by the C preprocessor prior to compilation.
Header files contain declarations required by the program. In this case,
because the main program uses the printf()
function, we must
include the standard input/output header which contains an appropriate
declaration for this function.
Note that there are several differences between this program and the precending Java program:
For example, the C main()
program is not included inside
a class. C has no concept of classes. The main()
function
as well as the printf()
function are essentially at global
(or top-level) scope in the C program. The Java main()
function also has an argument, an array of Strings
which represent the command line arguments passed to the program.
C's main()
function can also access its command line
arguments but two arguments are required by the main()
program. (More on this in later lectures.)
The return 0;
at the end of the C program is the value
returned by the main()
program to the command shell.
A return code of zero is typically used by C
to represent successful completion of a program or a function.
The return type of the main()
function (and indeed all
functions in C) is designated at the beginning of its definition:
int main()
. Java, on the other hand does
not return a value for main()
.
Before downloading and compiling this program, it would probably be a good idea create a separate directory for your 3710 source code and do all your work in that directory. To copy this source code, right click on the source code and select the Save Link As... option in the menu and save the file to your 3710 directory.
You can then compile and execute the program. This source file can be compiled on a typical Unix machine from a command line prompt as follows:
Method #1: Use the gcc compiler to compile the source program as follows:
$ gcc hello1.c
This will create a file called a.out
which can then be
executed as follows:
$ ./a.out Hello World!
You can also specify various flags to gcc
to tell
the compiler to generate warnings when it sees something in your
code that may cause problems. You can turn on these warnings
by invoking gcc
as follows:
$ gcc -Wall -ansi -pedantic hello1.c -o hello1 $ ./hello1 Hello World!
The -o
option tells the C compiler where to store the
resulting executable. In the example above, we write the executable
in the file hello1
, instead of a.out
.
Now, to run the program, we type ./hello1
. The compiler
options -Wall -ansi -pedantic
can generate useful
diagnostics regarding your code that can be especially helpful when
learning C for the first time.
Method #2: The program make can also be used to compile a variety of programming languages. Typically a Makefile is required for complicated programming projects, but for simple, single file programs, you can simply type:
$ make hello1
This will automatically compile the hello1.c source file in
the current directory and create an executable hello1
which can then be executed as follows:
$ ./hello1 Hello World!
Note that unlike the Java compiler, which generates byte-code (which must be interpreted), the C compiler generates an executable which can be run natively on the hardware without the use of an interpreter. As a result of this C programs are typically much faster than Java programs on the same hardware.
As described above, the preprocessor is executed prior to the compiler.
During the preprocessing, #include
directives are followed
and #define
macros (which will be described later) will be
substituted throughout the source file.
If you would like to see the output of the preprocessor, run the
compiler with the -E
option:
$ gcc -E hello1.c
More than 800 lines of code is generated by this command with the
main()
program located at the bottom. This is the source
that the compiler actually uses when compiling the hello1.c
program.
If you'd like to scroll back and forth through the output, you
can pipe the output to a pager program (e.g. less
)
as follows:
$ gcc -E hello1.c |less
In the above command, we pipe the output of the preprocessor to
less
which allows you you move through the standard output
of the compiler's preprocessor output by using the space bar to move
forward and pressing Ctrl-U
to move up. You can go
directly to the end of the output by pressing G
.
You can terminate the pager by pressing q
.
Apart from the minor syntactic differences, the C++ program is very similar to the C program.
/* Source file hello2.cpp */
#include <iostream>
int
main()
{
std::cout << "Hello world!" << std::endl;
return 0;
}
hello2.cpp
We now include the iostream
header instead of
stdio.h
(note the absence of the .h extension from
iostream
). Also, instead of printf()
, we use
the std::cout
standard output object and the insertion
operator (<<
) to send data to standard output.
The std::endl
represents the end of line character
and is analogous to the \n
(newline) character in
the C. Incidentally, the std::
prefix indicates that
cout
and endl
are defined in the context of
the standard library's namespace.
Again, you can compile and execute this program in a manner similar to above.
Method #1: Use the g++ compiler to compile the source program as follows:
$ g++ hello2.cpp
Again, this will create a file called a.out
(which overwrites
any existing a.out
file). This executable can then be run:
$ ./a.out Hello World!
The compiler options described above for generating warnings and for
writing the executable to another file instead of a.out
are
available to g++
as well. Using them when compiling your
programs can be very helpful.
Method #2: Again, we can use the make program to build a executable from this source file:
$ make hello2
This will now use the C++ compiler to compile the hello1.cpp
source file in the current directory and create an executable
hello2
which can then be executed:
$ ./hello2 Hello World!
Unlike C and C++ programs, perl programs are not compiled to a binary executable prior to being executed. Instead, a perl script is both compiled to an internal form and then executed all in one step.
#!/usr/bin/perl -w
#
# Source file hello3.pl
use strict;
print "Hello world!\n";
hello3.pl
To run this program, you must first download it and turn on
the execute permissions of the downloaded file. If we look at the long
listing of the script, you notice that the user's permissions on a newly
created file are usually set to read/write with no execution permission
as indicated by the second, third and fourth characters (rw-
)
of the output below:
$ ls -l hello3.pl -rw-r--r-- 1 donald cs-grad 83 Jan 5 23:50 hello3.pl
We can turn on the execute bit for the user (i.e. the owner of the file)
by using the chmod
command as follows:
$ chmod u+x hello3.pl
Note that it is only necessary to change the permissions once -- it is
not necessary to change it everytime we want to run the perl script.
Running the ls
command now shows that the script has the
appropriate permissions (the execute bit x
is now set on
the file permission) :
$ ls -l hello3.pl -rwxr--r-- 1 donald cs-grad 83 Jan 5 23:50 hello3.pl
You can then compile/execute it be calling the script by name:
$ ./hello3.pl Hello world!
The first line in the perl script is special. Upon seeing the
'#!
' special characters at the beginning of the file, the
program immediately following these two characters will be executed to
run the script. The -w
option turns on warnings which can
provide very instructive output about potential problems in your code
when it is compiled and run.
Note that perl, like Java, is compiled internally to byte-code. However, the byte-code is not actually written to a file as they are when you compile a Java program. Instead, perl executes the byte-code immediately after it compiles the script (provided of courses, there were no compilation errors in the script).
A perl script can also be compiled and executed by invoking the perl executable directly on the command line. For example,
$ perl -w hello3.pl Hello world!
In this case, it is not necessary to have the execute permission on the
file set, nor is it necessary to have the first '#!...
' line
in the script.
Amongst other features, the use strict;
tells the compiler
to enforce declarations of variables before use -- this can be very
helpful when trying to find bugs in your perl programs. The use of
-w
and use strict;
is strongly encouraged for
all perl programs that you write.
Note that the perl program presented above does not explicity return a value to the invoking shell. In this case, perl will return 0, by default.
Another common way to run perl scripts is to use the -e
option and specify the entire perl program directly on the on the
command line enclosed in single quotes:
$ perl -e 'print "Hello world!\n"' Hello world!
Of course, this is useful only for relatively small perl scripts. However, because you can express a lot of functionality with very little perl, executing perl scripts this way is not unusal.
Last modified: March 31, 2004 15:17:00 NST (Wednesday)