Working on arrays and hash tables
In C, there are two different basic methods for storing any number of independent data elements in a struct. Both of these methods have pros and cons.
Vector Vs. Linked list
Application writing is usually based on the selection of characteristics of specific types of data, how much data is stored, and how fast the retrieval is required. To be able to have peer recognition, let's take a look at these storage mechanisms briefly.
Vector
A vector is a contiguous memory space that contains a regular interval of data. The most common example of a vector is a string variable (char * or char []) that contains a sequence of characters (bytes) followed by one.
Char foo[4] = "Bar";
Here, Foo[0] contains the character ' B '; Immediately thereafter, you will find the character ' a ' in foo[1], and the last in Foo[3] is an empty character '.
It is almost ubiquitous to store pointers to other structures in vectors, such as in the previous chapter, when using the ZEND_GET_PARAMETERS_ARRAY_EX () function, a zval vector is used. There, we see that var_dump () defines a zval function variable, and then allocates space for it to store zval * * Pointers (final data from ZEND_GET_PARAMETERS_EX () invocation)
Zval ***args = Safe_emalloc (Zend_num_args (), sizeof (zval**), 0);
and access the array in the string, the Var_dump () implementation uses args[i] to pass each zval-* element to the internal function php_var_dump () in turn.
The greatest advantage of vectors is the speed at which individual elements are accessed at run time. Args[i] Such a variable reference can quickly compute its data address (args + i * sizeof (ARGS[0)). The spatial allocation and release of this index structure is done in a single, efficient invocation.
Linked list
Another common way to store data is linked lists. For a linked list, each data element is a struct with at least two attributes: one point to the next node in the list, and one is the actual data. Consider the following hypothetical data structure:
typedef struct _NAMELIST namelist;
struct {
struct namelist *next;
char *name;
} _namelist;
Using a reference to this data structure requires defining a variable:
Static NameList *people;
The first name in the list can be obtained by checking the Name property of the people variable: people->name; The second name accesses the next property: People->next->name, and so on: People->next->next->name, and so on, until next is null to indicate that there are no more names in the list. A more common usage is to use a cyclic iteration list:
void Name_show (NameList *p)
{
while (p) {
printf ("Name:%s\n", p->name);
p = p->next;
}
}
This list is ideal for FIFO chain structures, where new data is appended to the end of the list, and the data is consumed linearly from the other end:
static NameList *people = null, *last_person = NULL;
void Name_add (NameList *person)
{
person->next = NULL;
if (!last_person) {
* * * Linked list NO data * * *
people = Last_person = person;
return;
}
/* Add new data to the end of the list * *
last_person->next = person;
/* Update list tail pointer
/Last_person = person;
}
NameList *name_pop (void)
{
NameList *first_person = people;
if (people) {
people = people->next;
}
return First_person;
}