Zhou Ligong teaches you to learn C language programming: teach you how arrays save pointers

The first chapter of this article lays the foundation of programming. Here we discuss an array of pointers starting from version 1.8.3. These pointers can be used to manage and manipulate data efficiently. The concept of pointers is fundamental in understanding how data is stored and accessed in computer memory.

> > > > 1. String and Pointer Array

Consider 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 store pointers, and you can create a derived type based on the basic data type. This means grouping together the same type of pointer variables to form an array of pointers. You can store an address in each element of the pointer array variable and differentiate them using subscripts. While both arrays and pointer arrays store data, there are subtle differences between them. Arrays 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 implies that ptr is an array of pointers to int (with three elements), and the type name "int *[3]" means an array of three pointers to int. Essentially, ptr is an array of three pointer-type elements. The 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 the pointer is dereferenced by *ptr[i] (where i=0~2), the content of this address is obtained, i.e., *ptr[0]==1, *ptr[1]==2, *ptr[2]==3. You can also use equivalent pointer notation, where ptr+i represents the address of the i-th 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], the expression ptr+1 returns &ptr[1], *(ptr+1) gets the pointer &data1, and **(ptr+i) dereferenced gives the content &data1, which is "1". Using the pointer notation allows us to understand that we're dealing with an array of pointers.

Clearly, if you initialize a pointer array variable to hold the first address of each string, you can reference 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. That is, all the characters of the i-th string are stored in a certain position in memory, and the pointer pointing to it is stored in keyWord[i]. So, 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 string it can access can be any length. This flexibility is a powerful demonstration of C's robust data structuring capabilities. Since a pointer array is an array of elements as pointer variables, an array of character pointers can be used to process multiple strings. It’s evident that using a pointer array is better than using a switch statement to make a string into a pointer array. This approach allows data to be stored in two forms: storage address and stored value, 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 enables flexible storage and sorting of data from any complex structure.

Figure 1.14 Addressing method

On the contrary, value-based storage packs data sets of n elements into a fixed-size record block. The fixed size is s. The storage method is illustrated 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, you can leverage this feature and use the void* pointer as a formal parameter of the byte_swap() function to accept any type of data.

Since the smallest variable in C is a char type (including unsigned char, signed char, etc.), the result of sizeof(char) is 1, and the size of any other variable is an integer multiple of it. For example, in a 32-bit system, sizeof(int) is 4. Since the variable types of the C language are diverse, it is impossible to number each variable type, and swapping does not care about the true type of the variable, so the variable type can replace the variable 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 is > 0, it means pData1 > pData2.

Here, any type of pointer can be passed into byte_swap(), which truly represents the meaning of the memory operation function. Regardless of the data type of the memory, the object it operates on is just a piece of memory. No matter what type the user is passing in, from the C99 version, 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 cycle 4 times. The premise is that the two variables must be of the same type. For example, the values of the two variables a and b are exchanged. 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 Listing 1.42 and Listing 1.43.

Program 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(" ");

12 }

13

14 int main(int argc, char *argv[])

15 {

16 show_str();

17

18 if(strcmp(keyWord[0], keyWord[1]) < 0)

19 byte_swap(keyWord, keyWord +1, sizeof(keyWord[0]));

20 show_str();

21 return 0;

22 }

Solar&Wind Power Generator

Solar Generator,Wind Power Generator,Home Generators,Solar Generator

Shaoxing AnFu Energy Equipment Co.Ltd , https://www.sxanfu.com

Posted on