Pointer variable, array pointer, pointer array, level 2 array, function pointer, void pointer

preface

Pointer is not only the key point of c language, but also the difficulty of c language. Generally, we won't make mistakes in the simplest pointer variables. We can encounter pointer array, array pointer, two-dimensional pointer, three-dimensional pointer, function pointer and void pointer. Sometimes it gets confused. Today, I spend a day studying and sorting it out for future reference to prevent us from using it less and forgetting it after learning.

Pointer variable

Ordinary variables have addresses and values.

Pointer variables also have addresses and values, and the values are stored in other addresses (ordinary variable addresses).

*name accesses other values (ordinary variable values).

Other type, the type declared by pointer variable, is the type of other value (ordinary variable type).

Pointer variables + n,-n are offset up and down at the position of other address (n * sizeof (other type)).

Pointer variable summary period:

Value save other address, * visit other value.

Array, 2D array, pointer array, array pointer, the difference between 2D pointer

Normal array

#include <stdio.h>

int main()
{
    int arr[4] = {1,2,3,5};
    printf("arr[0] address = %x\n",&(arr[0]));
    printf("arr[1] address = %x\n",&(arr[1]));
    printf("arr[2] address = %x\n",&(arr[2]));

    printf("&(*(arr)) address = %x\n",&(*(arr)));
    printf("&(*(arr + 1)) address = %x\n",&(*(arr + 1)));
    printf("&(*(arr + 2)) address = %x\n",&(*(arr + 2)));

    printf("arr address = %x\n",arr);
    printf("arr + 1) address = %x\n",arr + 1);
    printf("arr + 2) address = %x\n",arr + 2);

    printf("*arr value = %d\n",*arr);
    printf("*(arr + 1) value = %d\n",*(arr + 1));
    printf("*(arr + 2) value = %d\n",*(arr + 2));

    printf("arr address = %x\n",&(arr));
    printf("arr address + 1 = %x\n",&(arr) + 1);
    printf("arr address + 2 = %x\n",&(arr) + 2);
    

    printf("arr address + 1 = %x\n",&arr + 1);
    printf("arr address + 2 = %x\n",&arr + 2);
    printf("arr address + 3 = %x\n",&arr + 3);
    return 0;
}

Subscript access address

arr[0] address = c7365bb0
arr[1] address = c7365bb4
arr[2] address = c7365bb8

*No. take address
&(*(arr)) address = c7365bb0
&(*(arr + 1)) address = c7365bb4
&(*(arr + 2)) address = c7365bb8

arr value
arr address = c7365bb0
arr + 1) address = c7365bb4
arr + 2) address = c7365bb8

Other value
*arr value = 1
*(arr + 1) value = 2
*(arr + 2) value = 3

Own address
arr address = c7365bb0
arr address + 1 = c7365bc0
arr address + 2 = c7365bd0

Summary:

arr is actually a constant pointer. It's very strange that its value address is the same as its own address. I call it a pointer to itself.

After definition, arr cannot be re assigned.

arr points to the first address of the array. (address type is int)

&Arr own address. (address type is int[4]) + 1 will offset sizeof(int) * 4

Two dimensional array

    int arrs[2][3] = {{1,2,3},{3,4,5}};

    printf("arrs[0] address = %x\n",&(arrs[0]));
    printf("arrs[0][0] address = %x\n",&(arrs[0][0]));
    printf("arrs[0][1] address = %x\n",&(arrs[0][1]));
    printf("arrs[1] address = %x\n",&(arrs[1]));

    printf("&(*(arrs) address = %x\n",&(*(arrs)));
    printf("&(*(arrs + 1) address = %x\n",&(*(arrs + 1)));

    printf("arrs address = %x\n",arrs);
    printf("arrs + 1 address = %x\n",arrs + 1);
    
    printf("&arrs address = %x\n",&arrs);
    printf("&arrs + 1 address = %x\n",&arrs + 1);

    printf("(*arrs) + 1 address = %x\n",(*arrs) + 1);

    printf("arr[1][2] value = %d\n", *(*(arrs + 1)) + 2);

arrs[0] address = a892b070
arrs[0][0] address = a892b070
arrs[0][1] address = a892b074
arrs[1] address = a892b07c
&(*(arrs) address = a892b070
&(*(arrs + 1) address = a892b07c
arrs address = a892b070
arrs + 1 address = a892b07c
&arrs address = a892b070
&arrs + 1 address = a892b088
(*arrs) + 1 address = a892b074
arr[1][2] value = 5
 

The difference between two-dimensional array and one-dimensional data: self address, self value, other value, and the rise of operation dimension.

&ARRS address, value type (int[2][3]), offset sizeof(int) * 2 * 3

arrs has its own value, the value type is (int[3]) arrs + 1, and the offset is sizeof(int) * 3

*arrs other values, the value is (int[3] the first address of the array), the value type is (int) arr + 1 is sizeof (int)

*(* arrs), the value is int

Array pointer

    int (*p)[3];
    int a[2][3] = {{1,2,3},{4,5,6}};

    p = a;
    printf("&p address = %x\n",&p);
    printf("p address = %x\n",p);
    printf("p+1 address = %x\n",p + 1);
    printf("a[1][1] address = %x\n",(*(p + 1) + 1));
    printf("a[1][1] = %d\n",*(*(p + 1) + 1));

&p address = af57d528
p address = af57d510
p+1 address = af57d51c
a[1][1] address = af57d520
a[1][1] = 5
 

p defined here is a pointer variable that points to an array with a length of 3. Equivalent to a line pointer.

& Address: it is the address of the pointer variable. The value type is (int *) and the offset is sizeof (int *)

Self value (p): the first address of the array with a length of 3. The value type is (int[3]) and the offset is sizeof (int) * 3

Other value (* p): the value of the first address of the 2-dimensional group (that is, a[0]). The value type is (int) and the offset is sizeof(int)

The value of a[0] is the first address of the 1-dimensional array.

*(* p + i) + j): the value of other value a[i][j] position of other value

Pointer array

int *p[3];
    int a[2][3] = {{1,2,3},{4,5,6}};
    int i;
    for (i = 0; i < 3; i++)
    {
        printf("&(p + %d) address = %x\n",i,&(p) + i);
        printf("&(p[%d]) address = %x\n",i,&(p[i]));
        printf("&(*(p + %d)) address = %x\n",i,&(*(p + i)));
    }
    p[0] = &a[1][1];
    p[1] = a[0];
    printf("*p[0] value = %d\n",*(p[0]));
    printf("*p[0] value = %d\n",*(*(p)));

    printf("a[0][1] value = %d\n",*(p[1] + 1));
    printf("a[0][1] value = %d\n",*(*(p + 1) + 1));

&(p + 0) address = bf0e30e0
&(p[0]) address = bf0e30e0
&(*(p + 0)) address = bf0e30e0
&(p + 1) address = bf0e30f8
&(p[1]) address = bf0e30e8
&(*(p + 1)) address = bf0e30e8
&(p + 2) address = bf0e3110
&(p[2]) address = bf0e30f0
&(*(p + 2)) address = bf0e30f0
*p[0] value = 5
*p[0] value = 5
a[0][1] value = 2
a[0][1] value = 2
 

p is actually an array with a length of 3 and a type of pointer.

& Address (sizeof: int *) with the first value of sizeof: int *)

Self value (p): the value of the first address p[0], the value type is (int *), and the offset is sizeof(int *)

Other value (* p): equivalent to * p[0], the value type is (int), and the offset is sizeof(int)

*(* p + i) + j): the value of other value a[i][j] position of other value

 

Difference between array pointer and pointer array:

Array pointer is a pointer, and pointer array is multiple pointers.

They are opposite in self address and self value type.

 

Secondary pointer

    int **p = NULL;
    int *p1 = NULL;
    int a[2][3] = {{1,2,3},{4,5,6}};
    p1 = a[0];
    p = &p1;

    printf("p1 address = %x\n",&p1);
    printf("p1 + 1 address = %x\n",&p1 + 1);
    printf("p1 value = %x\n",p1);
    printf("p address = %x\n",&p);
    printf("p + 1 address = %x\n",&p + 1);
    printf("p value = %x\n",p);

    printf("p1 a[0][1] value = %d\n",*(p1 + 1));
    printf("p a[0][1] value = %d\n",*(*(p) + 1));
    return 0;

p1 address = b000e120
p1 + 1 address = b000e128
p1 value = b000e100
p address = b000e128
p + 1 address = b000e130
p value = b000e120
p1 a[0][1] value = 2
p a[0][1] value = 2

p is a pointer to a first level pointer

& Address: value type is (int * *), offset is sizeof(int * *)

Self value (p): the value type is (int *), and the offset is sizeof(int *)

Other value (* p): the value type is (int *), and the offset is sizeof(int *)

*(* p + i) + j): the value of other value a[i][j] position of other value

Function pointer

    int (*f)(int);
    f = fun;
    printf("f address = %x\n",&f);
    printf("fun address = %x\n",&fun);
    printf("*f address = %x\n",*f);
    f(1);

f address = f49988e8
fun address = 40052d
*f address = 40052d
fun 1
p is a function entry address that points to a return value of int and parameter 1 of int.

 

void pointer

If the type of pointer is not clear, any pointer can be assigned to the void pointer.

It is often used in generic programming as a parameter of public interface function.

Keywords: C pointer

Added by vivekjain on Mon, 07 Feb 2022 15:06:51 +0200