Running a program

On a command line system, programs are run by entering lines such as the following.
	pwd
	mkdir pa5
	cp file1 file2
	my-program
	gcc source.c -o prog
	javac Prog1.java
	java Prog1
In each case, the program that is to run is specified by the first "word" in the command line. That program executes in its own virtual world provided by the operating system. In the above examples, the programs pwd, mkdir, cp, my-program, gcc, javac, and java are executed.
  • In the last example above, what is executing in a virtual environment?
  • In DOS or Linux, how does the command interpreter know where to find the programs named on command lines?

    When the program terminates, a "termination" status is returned to the command line interpreter. By convention, a termination status of 0 indicates the program terminated normally, and non-zero termination status indicates the program terminated abnormally. For example, mkdir returns 0 if it makes the specified directory but returns non-zero if it could not make the directory. A compiler returns 0 of the source code compiled without error, but it returns non-zero if it detects one or more errors in the code.

    Both DOS and Linux can make use of the termination status. After calling the compiler to compile source code, the following line runs the program only if the compile was successful.

    	[ $? = 0 ] && prog	# linux
    	if errorlevel 0 prog	# DOS
    

  • What in Java specifies the "termination" status?

    In the case of Java and C (and C++), program execution begins with a call the the function main. The "words" on the command line are passed to the program via the main function argument list. In Java and C, the main declaration would be as follows.

    	public static void main (string args[])	// Java
    	int main (int argc, char *(args[]))	// C (and C++)
    
  • Why is the return type void for java and int for C?
  • What is argc?
  • What does the C args declaration mean?

    Standard Input/Output

    The virtual environment that a program runs in has 1 "standard" input stream and 2 "standard" output streams. Picture the streams as a "pipe" that connects to the program's virtual world. The program has no idea what is on the other end of the "pipe" it just can read characters coming in through the input pipe, and can send characters out through the output pipe. In Java, the I/O streams (pipes) are called System.in, System.out, System.err. In C, they are called stdin, stdout, stderr.

  • Why are there separate streams for normal and error output?
  • Why are there not separate streams for normal and error input?

    File names

    In Java, source file names end in .java and the "base" name MUST match the name of the class defined in the source file. Object file names end in .class and the "base" name matches the name of the class defined in the source file. In C, there are no classes. Source file names should end in .c but the basename can be anything. As with variable names, C source file names should be meaningful. Object file names end with .o and use the same base name as the source file.

    Text files

    Source files, in Java or C, are "text" files. That is, they are files containing character text. Object files, pdf files, word files are examples of "binary" files, files not containing text. Each line of text in a text file should end with an "newline" indicator. In C and Java, this is the character '\n'. Be careful when using some editors, especially Windows editors. They may allow a file to be created where the last line of text does not end with a '\n'. Many programs, like compilers, when processing the imformation in such a source file will consider the missing newline an error.
  • On linux, a text file contains a single line with the characters "123". How many bytes in the file?
  • On windows, a text file contains a single line with the characters "123". How many bytes in the file?

    Linking

    In Java, there are just source files and object files. On the command line, the java program is specified with an argument naming the class containing main that is to be executed. Since the object file must be named the same as the class, the java program finds that file and executes it. If that code calls code in any other classes, java will find the files containing those classes and execute them as well.
  • Where does java look for all these class files?

    With C, all the object files that make up a program must be linked into a single file called an executable file. The executable file may have any name but again programmers should choose meaningful names.

  • In Java and C, there are object file libraries containing useful code. A few examples of things in libraries are code to do input/output, manipulate strings, and perform math calculations. Where does java and the C linker know where to find all this library code?

    A simple C program

    	//---------------------------
    	// A totally useless program.
    	//---------------------------
    	int main (int argc, char *(args[]))
            	{
    		int	status;		// Program exit status
    		int	ii;		// An index into the array
    		char	str[10];	// An array of chars (string)
    		
    		//-----------------------------------
    		// Assign the string "ab" into `str'.
    		//-----------------------------------
    		ii = 0;
    		str[ii++] = 'a';
    		str[ii++] = 'b';
    		str[ii++] = '\0';
    		if (ii == 10)
    			status = 1;
    		else
    			status = 0;
            	return status;		// Style: only at end! Why?
            	}
    

    Some familiar stuff

    1. Types
      1. int
      2. short
      3. long
      4. long long
      5. unsigned int
      6. char
      7. unsigned char
      8. float
      9. double
      • What is missing from this list?
      • Can you assign an int into a char?
      • Can you assign an int into a int?
    2. Constants
      1. 22
      2. 022
      3. 'c'
      4. '\t' /* TAB */
      5. '\0 /* NEWLINE */
      6. "abc"
      7. 5.2
      8. .2
      9. 5.
      10. 5e4
      11. 5e+4
      12. 5e-4
      13. 5.2e9
      14. .2e9
      15. 5.e9
    3. Statements
              var = exp;
              if (exp)
                      {
                      // stmt list
                      }
              else    {
                      // stmt list
                      }
              while (exp)
                      {
                      // stmt list
                      }
      	switch (expr)
      		{
      	case CONST1:
                      // stmt list
      		break;
      	case CONST2:
                      // stmt list
      		break;
      	default:
                      // stmt list
      		break;
      		}
              break;
              continue;
      	return;
      	return 12;
      
    4. operators
      1. - a       /* unary minus */
      2. ! a       /* logical not */
      3. a * b       /* mult */
      4. a / b       /* div */
      5. a % b       /* remainder or mod */
      6. a + b       /* add */
      7. a - b       /* sub */
      8. a < b       /* less than */
      9. a > b       /* greater than */
      10. a <= b       /* less than equal */
      11. a >= b       /* greater than equal */
      12. a != b       /* inequality */
      13. a == b       /* equality */
      14. a && b       /* logical and */
      15. a || b       /* logical or */
      16. a.b       /* member b of a */
      17. a[b]       /* element b of array a */
      1. & a       /* address of, `a' must be a variable or a function */
      2. * a       /* indirection */
      3. ~ a       /* bit not */
      4. ++ a       /* pre-increment */
      5. a ++       /* post-increment */
      6. -- a       /* pre-decrement */
      7. a --       /* post-decrement */
      8. sizeof a       /* size in bytes of `a' */
      9. a << b       /* left shift */
      10. a >> b       /* right shift */
      11. a & b       /* bitwise and */
      12. a ^ b       /* bitwise xor */
      13. a | b       /* bitwise or */
      14. a = b       /* assignment */
      15. a += b       /* a = a + b */
      16. a->b       /* (*a).b */

    Compiling and linking C

    	gcc -Wall -c t1.c		# t1.c => t1.o
    	gcc -Wall -c t1.c t2.c		# t1.c => t1.o. t2.c => t2.o
    	gcc -Wall t1.o -o tt		# t1.o => tt
    	gcc -Wall t1.o t2.o -o tt	# t1.o,t2.o => tt
    	gcc -Wall t1.o			# t1.o => a.out
    	gcc -Wall t1.c -o tt		# t1.c => tt
    

    Major pieces of a source file

    #include 
    #include "local.h"
    
    #define	CON	5
    
    extern	int	a1;  		// Permanent, global (import)   
    	int	a2;          	// Permanent, global (import or export)
    	int	a3 = 2;         // Permanent, global (export)
    static	char	b;          	// Permanent, private to file
    const	int	c = 3;		// Permanent, global (export), constant
    
    extern	double	func1(int);	// Function, global (declaration/import)
    	void	func2(char, int); // Function, global (declaration/import)
    static	int	func3(void);	// Function, private (declaration/import)
    static	int	func3b();	// BAD!!! (unknown parameters)
    
    static	int	func4(char p1, int p2)	// Function, private (definition/export)
    	{
    	int	a;			// Temporary, private
    	char	b;			// Temporary, private
    static	long	c;			// Permanent, private
    extern	double	func5(int);		// Permanent, global (import)
    
    	a = 1;
    	return 5;
    	}
    
  • All identifiers must be declared prior to any reference to them.
  • static is different from java, it is similar to "private".
  • import == declaration, export == definition
  • How do the declarations for func1 and func5 differ?

    Basic I/O

    	#include 
    
    	#define MAX_LINE_SZ	80
    	int	chr;	// Note: not a char
    	char	line[MAX_LINE_SZ+4];
    	int	len;
    
    	chr = getchar();
    	if (char != EOF) putchar(chr);
    
    	status = fgets(line, MAX_LINE_SZ+2, stdin);
    	if (status == NULL) exit(1); 
    	len = strlen(line);
    	if ( len > MAX_LINE_SZ) ...
    	
    	printf(format, a1, a2, ...);
    	fprintf(stderr, format, a1, a2, ...);