Stacks:
C, C++, and Java
Side-by-side


A stack program: Below is essentially the same stack implemented in C, C++, and Java. This is an array implementation. The code is arranged so that similar lines of each language are in a horizontal row with one another. To better illustrate the principles, this stack is ultimately stripped down, without even error checking. Each of the implementations takes place in a separate file, and each implementation is more-or-less how one might write code in the given language. Commentary about these approaches come after the code.

Even the C implementation achieves a key goal of an abstract data type: the method of implementation of the stack could be completely changed, say to a linked list form, without altering or even recompiling files that contain code making use of the stack. The C++ and Java stacks have this property also.

C Stack C++ Stack Java Stack









/* stack.h: header file */
void push( char );
char pop();
int empty();
int full();
-----------------------------

/* stack.c: stack implem */
#include "stack.h"


#define MAXSTACK 10
#define EMPTYSTACK -1
int top = EMPTYSTACK;
char items[MAXSTACK];




void push(char c) {
   items[++top] = c;
}

char pop() {
   return items[top--];
}

int full()  {
   return top+1 == MAXSTACK;
}

int empty()  {
   return top == EMPTYSTACK;
}

-----------------------------
/* stackmain.c: use stack */
#include <stdio.h>
#include "stack.h"

int main() {


   char ch;
   while ((ch = getchar())
         != '\n')
      if (!full()) push(ch);
   while (!empty())
      printf("%c", pop());
   printf("\n");
   return 0;
}

// stack.h: header file
class Stack {
   int MaxStack;
   int EmptyStack;
   int top;
   char* items;
public:
   Stack(int);
   ~Stack();
   void push(char);
   char pop();
   int empty();
   int full();
};
-------------------------------
// stack.cpp: stack functions
#include "stack.h"

Stack::Stack(int size) {
   MaxStack = size;
   EmptyStack = -1;
   top = EmptyStack;
   items = new char[MaxStack];
}

Stack::~Stack() {delete[] items;}

void Stack::push(char c) {
   items[++top] = c;
}

char Stack::pop() {
   return items[top--];
}

int Stack::full()  {
   return top + 1 == MaxStack;
}

int Stack::empty()  {
   return top == EmptyStack;
}

-------------------------------
// stackmain.cpp: use stack
#include <iostream.h>
#include "stack.h"

int main() {

   Stack s(10); // 10 chars
   char ch;
   while ((ch = cin.get()) 
         != '\n')
      if (!s.full()) s.push(ch);
   while (!s.empty())
      cout << s.pop();
   cout << endl;
   return 0;
}

// Stack.java: stack implementation
public class Stack {
   private int maxStack;
   private int emptyStack;
   private int top;
   private char[] items;




   



   



   public Stack(int size) {
      maxStack= size;
      emptyStack = -1;
      top = emptyStack;
      items = new char[maxStack];
   }

   

   public void push(char c) {
      items[++top] = c;
   }

   public char pop() {
      return items[top--];
   }

   public boolean full()  {
      return top + 1 == maxStack;
   }

   public boolean empty()  {
      return top == emptyStack;
   }
}
---------------------------------------
// Stackmain.java: use the stack
import java.io.*;
public class Stackmain {

  public static void main(String[] args)
       throws IOException {
    Stack s = new Stack(10); // 10 chars
    char ch;
    while ((ch = (char)System.in.read())
          != '\n')
       if (!s.full()) s.push(ch);
    while (!s.empty())
       System.out.print(s.pop());
    System.out.println();
  }
}
Execution of each program
% cc -o stack stack.c stackmain.c
% stack
mississippi
ppississim
% CC -o stack stack.cpp stackmain.cpp
stack.cpp:
stackmain.cpp:
% stack
mississippi
ppississim
% javac Stack.java
% javac Stackmain.java
% java Stackmain
mississippi
ppississim


Overview of the C Implemenation: This is the standard way to "fake" object-oriented programming in C: Use a separate file for the object, in this case stack.c. This allows for hidden data fields and hidden "member functions", as if they were declared private in the class of an object-oriented language. Data in the separate file is not accessible to the outside unless the data is declared extern. Functions can be protected from outside access by declaring them static, a very strange designator that should be called "private". The common connections between the stack implementation and its use occur in a header file, which is included below in each of the other files. This file is stack.h below. In this case the header file gives prototypes for the four functions that provide access to the stack. All variables related to the stack implementation are hidden in the implemenation file. The header file allows the stack implementation file and any file using the stack to be separately compiled.

This C implementation gives a single instance of a stack of chars of size 10. If one wants a stack of a different size, or of a different type, one must hack the code and recompile. If one wants several instances of this stack (or similar ones), one must make another copy of the file with separate external function names.


Overview of the C++ Implemenation: The C++ implementation achieves the goals of inaccessible data and only the desired stack management functions publicly accessible. Even this stripped-down C++ implementation gives far more than the C version: Here a program that uses the stack can instantiate as many stacks of different sizes as desired, and use them all simultaneously.

This same stack code could be written with C "templates" in such a way that a stacks of any type, including user-defined types, could be easily created. For a program that converts this stack code to a templated version, see C++ Stack Template

The C++ implementation uses a separate "header" file as shown, similar to the C header file. This gives an "overview" of the stack without the complete implementation, and allows separate compilation of the file to implement the stack and any file that uses the stack. As in C, the header file allows the stack implementation file and any file using the stack to be separately compiled.

This C++ code needs a separate destructor to recover the storage for the stack after it is no longer in use. This is because the one portion of storage is a dynamically allocated array which would not be deleted by the default destructor. Java uses automatic garbage collection, and so it doesn't need destructors.


Overview of the Java Implemenation: Many of the same comments given above for C++ apply to the Java implementation. Java doesn't have the C++ templates, but in Java one can create a stack of any type of object, and thus get the same features described above for C++, though the code will not be as efficient.

The Java implementation does not have a separate header file. In order to compile a file that uses this stack, the compiler must have access to the stack implementation file.

Java has the concept of an interface, which for a stack such as this would be a contract to implement the four given stack functions, by providing their prototypes in an interface declaration, and saying that the stack "implements" this interface.


Copyright © 2011, Neal R. Wagner. Permission is granted to access, download, share, and distribute, as long as this notice remains.