Level: elementary
Qiu Juntao
Juntao.qiu@gmail.com
), Software engineer, jinfonet
September 25, 2009
The object-oriented language is closer to the human way of thinking, which greatly reduces the complexity of the code and improves the readability and maintainability of the Code, traditional C code can also design beautiful code that is easier to read, easier to maintain, and less complex. This article will illustrate this through a practical example.
Basic knowledge
Struct
In addition to providing basic data types, the C language also provides users with the ability to customize data types, that is, struct. In the C language, you can use struct to represent any entity. Struct is the prototype of classes in object-oriented languages. For example:
typedef struct{ float x; float y; }Point;
|
Defines a point in a plane coordinate system. A point has two fields, X coordinate and Y coordinate.
The fields in the struct are called structMember
. The data type in the struct can be a simple data type or another struct, and even the struct itself can be nested. For example, a standard linked list structure can be defined as follows:
Typedef struct node { Void * data; // Data Pointer Int datalength; // Data Length Struct node * Next; // point to the next node } Node;
|
We can see that the next pointer type in the struct node is also the node type.
Function pointer
Pointers are the soul of the C language. They are more flexible and powerful than other languages. Therefore, to learn the C language, you must have a good grasp of the pointer. The function pointer refers to the pointer to the first address of the function in the memory ing. Through the function pointer, you can pass the function as a parameter to another function and call it when appropriate, to Implement Asynchronous Communication and other functions.
For example, the signal registration function in Unix/Linux is prototype as follows:
void (*signal(int signo,void (*func)(int))) (int) |
When using it, you need to define a signal processing function (signal handler) externally, and then use signal (signo, Handler) to register the processing program on the process. When the signal occurs, the process can call back the signal processing function.
Use the function pointer as a member of the struct.
As mentioned above, a struct member can be a simple data structure or another struct, or a pointer. When the function pointer is used as a member of the struct, and these functions are only used to operateBen
An independent entity can be formed when data in a struct. This entity contains both data and operations on data, which naturally leadsClass
(class)
.
Features of object-oriented language
I
In general, inheritance, encapsulation, and polymorphism are considered to be three features that must be supported by object-oriented languages. It is precisely through these three features that the forward object is superior to the process-oriented one. Because the language developer
On the surface, the object-oriented thinking needs to be implemented through language as the carrier. However, in fact, object-oriented thinking is a software design concept, it is completely unrelated to the specific implementation.
Even so, it is undeniable that these so-called pure object-oriented languages are much better than process-oriented languages in terms of code readability and matching with human natural thinking.
Language-level object-oriented
We generally want to describe an object. We usually need to describe some attributes of this object, such as the box(Box) is an entity, which has 6 faces, including color, weight, and whether it is empty, and can
Release
You can
Fetch
Something. In an object-oriented language, such an object is usually abstracted into a class ):
class Box{ clolr color; int weight; boolean empty;
put(something); something get(); }
|
You can perform the following operations on the box:
Box. Put (cake ); Box. Get (); // get something from the box.
|
In a process-oriented language, objects are usually transmitted to a global function. In the same case, box is often operated like this:
Put (box, cake); // put a cake in the box Get (box); // get something from the box
|
Obviously, the first form of code is more common sense. Therefore, most object-oriented languages provide detailed support at the language level, greatly increasing the readability and comprehensibility of the Code. C language, as a flexible and simple language, we can use the simple mechanism provided by C to implement such a beautiful code form.
C language object-oriented
As mentioned above, object-oriented is a software design concept and is language independent. In this section, I will give you a linked list(list)
The example shows how to design an object-oriented code in the C language.
Interface Definition
An interface is an important concept in object-oriented language. An interface only promises to external entities what functions the interface can accomplish, but does not expose the implementation method. The advantage is that the implementer can adjust the implementation without touching the code of the interface user.
Let's take a look at the Interface Definition of the linked list:
List 1. Linked List Interface Definition
# Ifndef _ ilist_h # DEFINE _ ilist_h
// Define the node Structure in the linked list Typedef struct node { Void * data; Struct node * next; } Node;
// Define the linked list Structure Typedef struct list { Struct list * _ this; Node * head; Int size; Void (* Insert) (void * node); // function pointer Void (* Drop) (void * node ); Void (* clear )(); INT (* getsize )(); Void * (* Get) (INT index ); Void (* print )(); } List;
Void insert (void * node ); Void drop (void * node ); Void clear (); Int getsize (); Void * Get (INT index ); Void print ();
# Endif/* _ ilist_h */
|
The ilist interface clearly shows that for a list object (that is, an object ),Above
Insert, drop, clear, getsize, get (INDEX), and print operations.
Interface implementation
Listing 2. Constructor
Node * node = NULL; List * List = NULL;
Void insert (void * node ); Void drop (void * node ); Void clear (); Int getsize (); Void print (); Void * Get (INT index );
List * listconstruction (){ List = (list *) malloc (sizeof (list )); Node = (node *) malloc (sizeof (node )); List-> head = node; List-> insert = insert; // register the insert function on the list object. List-> drop = drop; List-> clear = clear; List-> size = 0; List-> getsize = getsize; List-> Get = get; List-> Print = print; List-> _ this = List; // use the _ this pointer to save the List itself
Return (list *) List; } |
Note that the _ this pointer here can ensure that the external list operations are mapped to the _ this operation to simplify the code.
Listing 3. insert and delete
// Insert a node to a list object Void insert (void * node ){ Node * Current = (node *) malloc (sizeof (node ));
Current-> DATA = node; Current-> next = List-> _ this-> head-> next; List-> _ this-> head-> next = current; (List-> _ this-> size) ++; }
// Delete a specified Node Void drop (void * node ){ Node * t = List-> _ this-> head; Node * D = NULL; Int I = 0; For (I; I <list-> _ this-> size; I ++ ){ D = List-> _ this-> head-> next; If (D-> DATA = (node *) node)-> data ){ List-> _ this-> head-> next = D-> next; Free (d ); (List-> _ this-> size )--; Break; } Else { List-> _ this-> head = List-> _ this-> head-> next; } } List-> _ this-> head = T; } |
For other implementation code, refer to the download section. If the length is limited, it will not be meaningful.
Test
Test code
All the work we have done above is to ensure that the APIS we expose to users can be as concise and elegant as possible. Now it is time to test:
Listing 4. Test code
Int main (INT argc, char ** argv ){ List * List = (list *) listconstruction (); // construct a new linked list
// Insert some values for testing List-> insert ("apple "); List-> insert ("Borland "); List-> insert ("Cisco "); List-> insert ("Dell "); List-> insert ("Electrolux "); List-> insert ("Firefox "); List-> insert ("google ");
List-> Print (); // print the entire list
Printf ("list size = % d/N", list-> getsize ());
Node node; Node. Data = "Electrolux "; Node. Next = NULL; List-> drop (& node); // delete a node
Node. Data = "Cisco "; Node. Next = NULL; List-> drop (& node); // Delete another node
List-> Print (); // print again Printf ("list size = % d/N", list-> getsize ()); List-> clear (); // clear the list
Return 0; } |
Figure 1. Running result
Conclusion
The birth of C LanguageUNIX
Ping
The Platform advocates a design philosophy that allows users to connect these simple tools into powerful and complete applications just like building blocks. It should be said that C
It is better to inherit this point. The C language is very concise and powerful. The idea of object-oriented at that time was not mature due to the early birth of the C language, therefore, a large number of procedural C
To give people the illusion that a C language is a process-oriented language.
It only provides some simple, powerful, and general capabilities. As for what kind of building blocks you want to build, you are all dependent on yourself.