After 2 blogs on completely different things, it’s finally my turn to go techie. Something which I have always believed I was born to be. A couple of weeks into learning Java, I just couldn’t help but compare it to my beloved C. This is not a comprehensive comparison, as I think it would take an entire book to do that. Neither do I have the time, nor do I have the patience to write that much right now. I don’t make any comments on my knowledge.
I will make sincere effort to make it as unbiased as possible, but sometimes I just can’t help myself, as C is the language in which I think. And to be frank, these languages have their own strength and weaknesses, which can’t be weighed against in all circumstances.
First of all C was developed with system software in mind, the honor going to revered Dennis Ritchie. That was the time when programmers thought about the intricacies of the instruction execution being handled by the processor. What was required at that time was a straight-forward compiler which can translate high-level code into machine code. It was intended for an elite community of programmers who would make minimal number of errors. (“No offense to the try-catch way of thinking being enforced by the Java textbooks”). The basic assumption was that the programmer using C will know exactly what his code is going to do, which is not entirely true anymore.
By the time Java came up, there were a plethora of machines using different kinds of OS running on entirely different architectures. So the focus was on creating a language which is portable, and easy to program. Although it is not difficult to write a portable code in C, it requires a re-compilation which is what Java claims to eliminate. As the kids playing with Java say, Java has a Virtual Machine (which acts as an intermediate interpreter) to convert the byte code to machine code. This has actually made me wonder why they created an intermediate byte code concept. Why didn’t they create something which can directly run the Java code? Well, my guess would be that doing this would have resulted in Java being called a scripting language.
Anyway, Java has a very good support for multithreading and networking, and according to me this is probably one of the main factors which gave it the popularity that it has now. To be frank, implementing these in C requires a lot of effort and time in addition to the knowledge. During the 90’s when internet was fast developing, developing applications in minimal time was a priority. Because of these numerous inherent functionalities that Java provides, programming in Java is all about knowing the language. In comparison, C language is very simple and concise; programming in C requires using a good amount of ingenuity to use the limited resources to satisfy limitless possibilities.
The first example that comes to my mind is the use of function pointers in C. Any complex code in C involves function pointers (I don’t call others complex btw). You need to implement them if you want to implement a call-back mechanism. At the same time Java offers a more obvious way of doing the same using the concept of abstract class. (Note that the same thing can be implemented in a cruder way using interface). Let me give you a code snippet to ponder.
Background: For a particular set of data available, an operator has to operate upon, the type of operator being known only at runtime.
This is what I would use in C:
int Operate(int *operate_function (int, int), int data1, int data2) {
out = operate_function(data1, data2);
}
The function pointer operate_function will point to one implementation which will be chosen dynamically. The different implementations can be done using different functions with the same parameter list and return value.
Now in Java,
abstract class operator {
abstract int operate(int data1, int data2);
}
Class operator1 extends operator {
int operate(int data1, int data2) {
return funct1(data1, data2);
}
}
Class operator2 extends operator {
int operate(int data1, int data2) {
return funct1(data1, data2);
}
}
operator dynop;
dynop = new operator1();// or new operator2() which is to be decided dynamically.
out = dynop.operate(data1, data2);
Object-oriented Implementation in C:
If there is anyone thinking that OO concepts can only be implemented in OO languages, then this is what I would tell them. “I don’t know about other languages, but they definitely can be implemented in C”. And by the way, almost all of them use function pointers. Well, here is how:
1. Data Abstraction
Isn’t it all about hiding the details of the implementation, which is what I have described above?
2. Data Encapsulation
Again, function pointers come into play here. You define a structure containing a function pointer which points to the function to be performed on its data, and what you get is data encapsulation.
3. Inheritance
Well, this is simple. I will use a code snippet here.
typedef struct super {
int a, b;
};
typedef struct child {
super sup;
int c,d;
};
You got it.
4. Modularity
I don’t think anybody questioned the modular nature of C. If they do let them remember that functions are the way to implement modularity.
5. Polymorphism
Function pointer is back. We need to go a step further from our earlier discussion on function pointers. Here is how I am going to do it:
Suppose we need 2 implementations of a function add which looks like
- add(num1, num2)
- add(num1, num2, num3)
The overloading can be done like this:
typedef struct {
int n1;
}numArr1;
typedef struct {
int n1;
int n2;
}numArr2;
typedef union {
numArr1 num1;
numArr2 num2;
}utype;
Define the functions to do the operations:
int add_numarr1(int n1, numArr1 narr1) {
return n1+narr1.num1.n1;
}
int add_numarr2(int n1, numArr2 narr2) {
return n1+narr2.num2n1+ narr2.num2.n2;
}
Now define the function pointer:
int (*add)(num1, utype numarr);
Now, what will you do if you want to have overloading involving different data types? The way is similar, and upon doing a google search, I found someone who has already done that. Here is the link: http://thewizardstower.org/thelibrary/programming/polyc.html
I did not really expect this to go so long, but I think it would not have made any sense unless I wrote what I have written. Hope this makes a good reading.
PS: The codes provided are only samples and no guarantee is provided as to whether they are compilable or not. However, I expect the code to work with minimal changes in which case, there shall be no litigation initiated from my side against the user for using it.