The first chapter lays the foundation for programming. This article provides an array of pointers, focusing on version 1.8.3. The topic revolves around string and pointer arrays, which are essential concepts in programming.
Suppose we have the following definitions:
int data0 = 1, data1 = 2, data2 = 3;
Int *ptr0 = &data0, *ptr1 = &data1, *ptr2 = &data2;
In reality, addresses are also considered data. Therefore, arrays can also hold pointers. By grouping similar pointer variables together, we can create an array of pointers. Each element of the pointer array stores an address, which can be accessed via subscripts. While both arrays and pointer arrays store data, they differ subtly. Arrays typically store characters or values of the same type, whereas arrays of pointers store pointers of the same type. For instance:
int data0, data1, data2;
int *ptr[3] = {&data0, &data1, &data2};
This declaration can be interpreted as an array of pointers to the int pointer (with three elements), and the "int *[3]" type name indicates an array of three pointers to int. Essentially, the ptr pointer array consists of three pointer-type array elements. The essence is an array of type int *[3]. Here, ptr[0] points to &data0, ptr[1] points to &data1, and ptr[2] points to &data2.
Since ptr is declared as an array of pointers, ptr[0] returns an address. When dereferenced using *ptr[i] (where i=0~2), the content of this address is obtained, i.e., *ptr[0]==1, *ptr[1]==2, *ptr[2]==3. Alternatively, you can use equivalent pointer notation, where ptr+i represents the address of the ith element of the array. To modify the content of this address, you can use *(ptr+i). If you dereference **(ptr+i) twice, you can return the location of the allocated memory and assign it a value. For example, ptr[1] is located at address &ptr[1], and the expression ptr+1 returns &ptr[1]. Using *(ptr+1) retrieves the pointer &data1, and then **(ptr+i) dereferences it to obtain the content "1". This demonstrates how pointer notation allows us to manipulate pointer arrays effectively.
Clearly, initializing a pointer array variable to hold the first address of each string enables referencing multiple strings:
char *keyWord[5] = {"eagle", "cat", "and", "dog", "ball"};
Here, the type of keyWord[0] is char*, and the type of &keyWord[0] is char **. Although these strings appear to be stored in the keyWord pointer array variable, the pointer array variable actually stores only the pointers, with each pointer pointing to the first character of its corresponding string. In other words, all the characters of the ith string are stored in a certain position in memory, and the pointer pointing to it is stored in keyWord[i]. Specifically, keyWord[0] points to "eagle", keyWord[1] points to "cat", keyWord[2] points to "and", keyWord[3] points to "dog", and keyWord[4] points to "ball".
Even though the size of keyWord is fixed, the strings it can access can be of any length. This flexibility showcases C's powerful data structuring capabilities. Since a pointer array consists of pointer-type elements, an array of character pointers can be used to handle multiple strings. Clearly, it is more efficient to use a switch statement to convert a string into a pointer array. This reveals that data is randomly stored in two forms: storing addresses and storing values, as shown in Figure 1.14. An array contains pointers to actual information, rather than storing information directly in the storage space of array elements. This approach allows flexible storage and sorting of data from any complex structure.
Figure 1.14 Addressing Method
Conversely, value-based storage packs data sets of n elements into a fixed-size record block. The fixed size is s. The storage method is shown in Figure 1.15. Each string occupies a continuous size of 6 bytes in the storage block.
Figure 1.15 Stored Value
To facilitate the description of multiple strings, a data exchange function will be designed. Since any data type pointer can assign a value to a void* pointer, this feature can be exploited by using the void* pointer as a formal parameter of the byte_swap() function to accept any type of data.
Since the smallest length variable in C is a char type (including unsigned char, signed char, etc.), the result of sizeof(char) is 1, and the length of any other variable is an integer multiple of it. For example, in a 32-bit system, sizeof(int) is 4. Because the variable types in C are diverse, it is impossible to assign each variable type a unique identifier, and the swap operation does not concern itself with the true type of the variable. Therefore, the variable type can replace the actual type. The byte_swap function prototype is:
void byte_swap(void *pData1, void *pData2, size_t stSize);
Here, size_t is a predefined type in the C language standard library, specifically for saving the size of variables. stSize is the length of the variable, and pData1 and pData2 are the first and second parameters to be compared, respectively. When the return value is < 0, it means pData1 < pData2; when the return value = 0, it means pData1 = pData2; when the return value > 0, it means pData1 > pData2.
With this design, any type of pointer can be passed into byte_swap(), which truly represents the meaning of a memory operation function. Regardless of the data type of the memory, the object it operates on is merely a piece of memory. No matter what type the user passes in, from the C99 version onward, when assigning a void * type pointer to another type pointer, no cast is required. That is, one byte is exchanged at a time, so for int type data, it only needs to loop 4 times. The剿 is that the two variables must be of the same type. For example, to swap the values of two variables a and b, the usage is as follows:
byte_swap(&a, &b, sizeof(a));
The interface and implementation of the byte_swap() data exchange function are detailed in Listings 1.42 and 1.43.
Listing 1.42 Swap Data Exchange Function Interface (swap.h)
1 #pragma once
2 void byte_swap(void *pData1, void *pData2, size_t stSize);
Listing 1.43 Implementation of the Swap Data Exchange Function Interface (swap.c)
1 void byte_swap(void *pData1, void *pData2, size_t stSize)
2 {
3 unsigned char *pcData1 = pData1;
4 unsigned char *pcData2 = pData2;
5 unsigned char ucTemp;
6
7 while (stSize--){
8 ucTemp = *pcData1; *pcData1 = *pcData2; *pcData2 = ucTemp;
9 pcData1++; pcData2++;
10 }
11 }
For a specific string, an application example of a pointer array is shown in Listing 1.44.
Listing 1.44 Compare String Size and Output Sample Program
1 #include
2 #include
3 #include "swap.h"
4
5 const char *keyWord[5] = {"eagle", "cat", "and", "dog", "ball"};
6 void show_str(void) // Print keyWord data
7 {
8 for (int i = 0; i < sizeof(keyWord) / sizeof(keyWord[0]); i++) {
9 printf("%s", keyWord[i]);
10 }
11 printf("\n");
12 }
13
14 int main(int argc, char *argv[]) {
15 show_str();
16
17 if (strcmp(keyWord[0], keyWord[1]) < 0)
18 byte_swap(keyWord, keyWord + 1, sizeof(keyWord[0]));
19 show_str();
20 return 0;
21}
Sealed Special Transformer,Oil Immersed Distribution Power Transformer,Low Noise Distribution Transformer,Oil Immersed Distribution Transformer
Shaoxing AnFu Energy Equipment Co.Ltd , https://www.sxanfu.com