[C Language] Potential connection between pointers and arrays

Table of contents

Preface

Change the flat thinking of inherent arrays

Notice:

Array operations are equivalent to pointers

array of pointers

array pointer

Written test to deepen understanding:

        Analysis:


Preface

        There is a famous insight in "C Traps and Pitfalls":

        "In C language, the connection between the two concepts of pointers and arrays is so inseparable that if you cannot understand one concept, you cannot fully understand the other concept."


Change the flat thinking of inherent arrays

        In essence, C language has only one-dimensional array, but the elements of the array can be any type of object, and of course it can also be a Array! So, this creates a high-dimensional array!


        For:

​int arr[6][4];

        In the above figure, arr is a one-dimensional array with six elements inside; the type of each element (arr[0], arr[1]...arr[5]) is an array type, assuming The elements arr[i][j] in this array (arr[0], arr[1]...arr[5]) are integers, then this array (arr[0], arr[1]. .....arr[5]) is of type int (*)[4] ;

        in other words:

        The arr declared by this statement is an array, which contains 6 array-type data, each element of which is an array of 4 integer elements. (Instead of an array with 4 array types, each element is an array with 6 integer elements)

        In fact, for the array arr, it is a main string (main array) with many substrings (subarrays) extending out; similar to the main stream of a river, there are many tributaries:

        It can be randomly distributed. For clarity, we usually draw a two-dimensional array into a two-dimensional checkerboard shape.

        We can actually draw the array into any distribution, as long as it meets the C standard: 

 (It’s difficult to demonstrate on a two-dimensional plane, so please figure out the distribution of each piece of cloth on the mop head by yourself)

       In fact, we can also get clues from the creation format of the array arr:

int arr[6][4];//请重新审视这段代码,以便于加深对他的理解

        This code can be translated as:

        Create an array named arr, the internal elements are 6 arrays of type int (*)[4]. In fact, it is to translate this code from front to back.

Notice:

         This idea of ​​​​understanding while translating is very important. If this idea is not adopted, it will be very difficult to understand and distinguish array pointers, pointer arrays, function pointers, and function pointer arrays!

Array operations are equivalent to pointers

        There are only two things we can do with an array:

        Determine the size of the array and obtain a pointer to the element at index 0 of the array.

        For other operations related to arrays, they are essentially pointer operations. That is to say: the operation of any array subscript is equivalent to the operation of a corresponding pointer. Therefore, pointer operations and array operations can be converted to each other.

        An array can be viewed as a collection of adjacent memory cells, and a pointer is a variable pointing to a memory address. Since an array is actually a contiguous memory space, pointers can be used to access elements in the array.

        Specifically, the array name can be regarded as a pointer to the first element of the array, that is, the array name itself is an address. Therefore, it is very convenient to use pointer variables to operate on arrays, as in the following example:


int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;   // 将数组名赋值给指针
for (int i = 0; i < 5; i++) {
  printf("%d ", *(p + i));  // 使用指针来访问元素

array of pointers

        The pointer array in C language refers to an array in which each element is a pointer. Such an array can be used to store multiple pointers in order to operate on them.

        For example, a pointer array can be used to store different types of pointers, such as integer pointers, character pointers, structure pointers, etc.:

int *ptrArray[10];     // 整型指针数组,包含10个元素
char *strArray[5];     // 字符型指针数组,包含5个元素
struct person *personArray[100];     // 结构体指针数组,包含100个元素

        You can access the elements in the array through subscripts and operate on them:

int a = 10, b = 20, c = 30;
int* ptrArray[3] = { &a, &b, &c };

for (int i = 0; i < 3; i++) {
    printf("%d ", *ptrArray[i]);    // 指针数组中的每个元素都是整型指针,需要使用 * 解引用
}

// 输出结果为:10 20 30

array pointer

        ​ ​ ​ In C language:

        Integer pointer variable: int * pint; stores the address of the integer variable, a pointer that can point to integer data.
        Floating-point pointer variable: float * pf; stores the address of a floating-point variable and can point to a pointer to floating-point data.
        The array pointer variable should be: it should store the address of the array, a pointer variable that can point to the array.


        An array pointer is essentially a pointer variable, but it can point to an array, allowing operations on the array.

Due to associativity issues, the way of writing array pointers is quite different from that of pointer arrays:

int *p1[10];
int (*p2)[10];

explain:

        ​ ​ 1. It is the pointer array introduced previously;

        2.p is first combined with *, indicating that p is a pointer variable variable, and then points to an array of 10 integers. So
        p is a pointer, pointing to an array


Note here: [ ] has a higher priority than *, so () must be added to ensure that p is combined with * first.

initialization:

int arr[10] = {0};
int(*p)[10] = &arr;

Initialize the array pointer using the address of the array. Moreover, the types of array pointers p and arr are the same.

This echoes the first part of this article, array pointers are the basis of high-dimensional arrays.


        Now that you have a certain knowledge base, you might as well do some test questions: 

Written test to deepen understanding:

Question 1:


#include <stdio.h>
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//#

int *ptr1 = (int *)(&aa + 1);//*

int *ptr2 = (int *)(*(aa + 1));//¥

printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));//&
return 0;
}

        Analysis:

        #OK:

        ​ ​ Initialize the array aa, aa has two rows and five columns;

        *OK:

        ​​​Create an integer pointer ptr1, take out the address +1 of aa, force the type to int*, and put it into ptr1;

        For address operations on arrays, +1 actually means skipping the entire array. At this time, ptr1 points to the address of an element immediately following the array.

        The type of expression is int (*)[5]. After forced type conversion, it is int*, which can be stored in ptr1.

        ¥ line:

        aa in aa+1 represents the address of the first element of the array, which is the address of int aa[0]. This is very important - this third time corresponds to the fact that the array aa is a one-dimensional array, and each element is also an array, then aa Each element in is an array type, instead of the element type in aa being int.

        aa + 1 means pointing to the second row, storing the address of the second row, indicating the address of the first element of the second row.

        .

result:


Finished~

Reprinting without the author's consent is prohibited 

Guess you like

Origin blog.csdn.net/2301_79465388/article/details/134520495