C language, a programming tool worth lifetime (2) ---- "Secret"

zhaozj2021-02-16  72

1. Object-oriented programming ideas

At that time, I thought c or learned, and various grammar were very familiar, what pointers, shifts, pointer arrays, and more. However, in practical applications, the size of the program written with C is not big, often feels that there is no sense of control on the program, the program is not flexible, and there are more events. At this time, it is just watching the "UNIX Advanced Tutorial System Technical Insider" in the middle of the VNODE / VFS architecture of the file system, "objects" in the C language. I was shocked at the time, and the C language has "object"? Take a closer look, really. The C language also has an object, but it is different in the expression and object-oriented language. And object-oriented thinking methods have been used in the development of UNIX systems.

The object in the C language is expressed in the form of a structure, which may include members of the general data type not only, but also a complex type of a function pointer. This is the so-called "abstraction" and "package". The function pointer in the structure is equivalent to the pure virtual function of the class.

C-object-oriented processing methods have a very wide application in UNIX systems, such as file systems, equipment drivers, and more. The following is a few famous examples of object-oriented ideological design.

UNIX block device structure (UNIX advanced tutorial P452):

Struct BDEVSW {

INT (* D_Open) ();

INT (* D_Close) ();

INT (* D_Strategy) ();

INT (* D_SIZE) ();

INT (* D_XHALT) ();

...

} BDEVSW [];

Linux file operation structure

Struct file_operations {

INT (* Lseek) (Struct Inode * Inode, Struct File * Filp, Off_T OFF, INT POS);

INT (Struct Inode * Inode, Struct File * Filp, Char * BUF, INT COUNT);

INT (* WRITE * Inode, Struct File * Filp, Char * BUF, INT Count);

INT (* readdir) (Struct File * Filp, Struct Dirent * Dream, int count);

INT (* SELECT) (Struct Inode * Inode, Struct File * Filp, int SEL_TYPE, SELECT_TABLE * WAIT);

INT (* IOCTL) (Struct Inode * Inode, Struct File * Filp, Unsigned INT CMD, Unsigned INT ARG);

INT (* mmap) (void);

INT (* Open) (Struct Inode * Inode, Struct File * Filp);

Void (* release * inode, struct file * filp);

INT (* fsync) (Struct Inode * Inode, Struct File * Filp);

}

Apache module

Typedef struct module_struct {

Int version;

Int minor_version;

INT Module_index;

Const char * name;

Void * Dynamic_Load_Handle;

Struct Module_struct * next;

Unsigned long Magic;

Void (* init) (Server_Rec *, pool *);

Void * (* create_dir_config) (pool * p, char * DIR);

Void * (* merge_dir_config) (pool * p, void * base_conf, void * new_conf); void * (* create_server_config) (POOL * P, Server_Rec * S);

Void * (* merge_server_config) (pool * p, void * base_conf, void * new_conf);

Const command_rec * cmds;

Const Handler_Rec * Handlers;

...

} Module;

Object-oriented programming methods in C language have already begun to apply. These concepts and methods have existed 20 or 30 years ago, nor "secrets". All basic knowledge speaking in the C language textbooks, the problem is only that we ignore how to use C language more effectively. Recognizing that C-object-oriented characteristics, the entire program, reliability, maintainability, and efficiency will have a leap.

Of course, compared to purely object-oriented, object-oriented characteristics of the C language seem to be original. But from another perspective, even these "original" features can solve 80% -90% of the problem.

2. C language "generic" --- void *

I believe that each programmer or more or less has been learned or has been used for some basic data structures, such as linked lists, haveh, table, trees, and more. In general, the data structure is mainly focused on the algorithm, and the method of implementation is not much attention. From the perspective of algorithm research, this is not very good. But for applications that need to be applied to data structures, it is often considered to be quite difficult in direct use of code. For example, the chain list is a substantially basic data structure, and the opportunity to use in the program is more. General practices: Define a structure that contains NEXT and PREVs, write related processing functions. For example, define the structure of a user information:

Struct SUSERINFO

{

Char Name [12 1];

CHAR MALE;

Int agec;

...

Struct SUSERINFO * PREV;

Struct SUSERINFO * NEXT;

}

The biggest problem with the above structure is that the code cannot be reused: the operation of the linked list is fixed, but the contents therebet are changed. For a new data, if you need to redefine the structure, copy code, the reuse of the code is poor, the development is low, and there are more opportunities for error. Is there a way to deal with these universal parts? The answer is yes, except for C , using the C language void * can also solve this problem.

Void * itself has no type, which can point to any pointer, of course, can point to the customized structural pointer. The following is part of the code that can support any type of two-way linked list:

/ ** Node in abstract linked list * /

Typedf struct SDBNode

{

Void * DN_PTR; / ** Node points to data pointer * /

Struct SDBNode * DN_PREV; / ** forward node * /

Struct SDBNode * DN_NEXT; / * * Back node * /

} SDBNOODE;

Typedef struct SDBLIST

{

Long dl_nums; / ** Number of nodes in the list * /

Struct SDBNode * DL_HEAD; / * * Link Top Pointer * /

Struct sdbnode * dl_tail; / ** Link list tail pointer * /

} Sdblist;

SDBLIST * DL_CREATE ()

{

SDBList * list;

List = (sdblist *) Malloc (SDBLIST)); MEMSET (List, 0, SIZEOF (SDBLIST));

Return List;

}

Void DL_INSERT_TAIL (SDBList * List, Void * Ptr)

{

SDBNode * node = malloc (sdbnode);

Node -> DN_PTR = PTR;

IF (List -> DL_NUMS == 0)

List -> DL_HEAD = Node;

Else

List -> dl_tail -> DN_NEXT = NODE;

Node -> DN_PREV = List -> DL_TAIL;

Node -> DN_NEXT = NULL;

List -> DL_TAIL = NODE;

List -> DL_NUMS ;

}

Void * dl_remove_tail (sdblist * list)

{

Void * p;

SDBNODE * NODE = List -> DL_TAIL;

IF (Node)

DL_Remove (List, node);

Else

Return NULL;

P = Node -> DN_PTR;

FreeP (Node);

Return P;

}

DoubleList's use

int main ()

{

INT I;

SUSERINFO * P;

SDBLIST * DL;

DL = DL_CREATE ();

For (i = 0; i <10; i )

{

P = Malloc (SizeOf SUSERINFO);

...

DL_INSERT_TAIL (DL, P);

}

...

}

Similarly, use VOID * can construct a general data structure such as Hash, Tree. These basic data structural code is undoubtedly our programming.

In addition, it is difficult to define the above code is not fully compliant with object-oriented programming methods. It is very simple from grammar to implementation, reusability. Whether to encapsulate the process function into the structure, implement the operation similar to DL.Insert_tail (& DL, PTR), or to be determined according to specific applications. The principle is to satisfy the demand, the better, the better, do not increase the complexity.

3. Basic processing mode of the C procedure

During the graduate process, a teacher's sentence, now I still remember: the company is most concerned about the data, the data is the core of the company, not the program. This sentence gave me a deep inspiration. After years of programming, it was found (in fact, it has been widely used):

In most programs, the code surrounds a small memory block in performing various logic processing, which is generally encapsulated by the structure. Define a structure or several interrelated structures based on appropriate applications is the basis and core of the entire system. Write various processing code around the core, these processing code is the business logic we want to implement. After forming a small core, the package and combination is made as needed to form a complex application.

The structure of multiple development source, such as Linux kernel, Apache, MySQL, etc., this processing method is all.

The two-way linked list mentioned in the previous section is such a small core.

4. Disadvantages of C language

The C language is a powerful programming tool. It is a good horse, but it is also a horse. If our experience and driving skills are insufficient, it is easy to be overturned by it; if it can control it well, You will find that it can be easily and fast to reach the destination.

First, the C language provides a powerful pointer function, and the pointer is an important feature of the C language. The memory can be operated directly by the pointer to achieve considerable flexibility and efficiency. But how to use the pointer correctly is a difficult point. Wonderful is wrong, it will cause the program to crash, which is also a place that is often accused. Second, use a good C language requires higher skills, as well as long-term self-improvement (equally applicable to other languages, but other languages ​​are relatively easy). This has a certain difficulty for beginners. In the case of basic concepts, it is difficult to correctly use certain characteristics of C language, which is easy to combat confidence.

Third, in-depth explanation of the information of C use and skills. Before the open source is popular, there are very few practical examples available for learning and reference. Many times, you can get these knowledge by applying for your experience and practice.

Fourth, the standard library is seriously insufficient. At present, the contents of the standard libraries defined by ANSI C are too small, and some basic data structures, such as linked lists, but not available. Although there are currently a lot of libraries, such as XML, encoded conversion, ZLIB, and more on the mainstream operating systems. However, since these libraries are not the standard libraries defined by ANSI C, they have a certain difficulty of use and transplant. (On the transplantation, Java has a certain advantage, the difficulty of C is larger)

转载请注明原文地址:https://www.9cbs.com/read-16604.html

New Post(0)