[C Advanced] 28. Pointer and array analysis

Posted by StealthRider on Sun, 02 Jan 2022 23:21:00 +0100

Summary

1) The array is a continuous memory space. The number of elements in the array is #define DIM(a) (sizeof(a) / sizeof(*a))

2) Pointer is a special variable. The operation rules between pointer and integer are as follows:
p + n; <--> (unsigned int)p + n * sizeof(*p)
When the pointer p points to an element in an array, p + 1 will point to the next element of the current element; p - 1 will point to the previous element of the current element.

3) Only subtraction is supported between pointers; Pointers participating in subtraction must be of the same type:
Note: pointer subtraction is meaningful only when two pointers point to elements in the same array. The meaning is the subscript difference of the element pointed to by the pointer; Undefined when the elements pointed to by 2 pointers are not in the same array.
p1 - p2; <--> ((unsigned int)p1 - (unsigned int)p2) / sizeof(type);

4)char* pEnd = s + DIM(s); pEnd points to the next position of the last element in the array s. Although this position does not belong to the array, in C language, it is still considered that this boundary position belongs to the array. This knowledge point is also applied in STL.

5) Pointers can also perform relational operations (<, < =, >, > =), but only if they point to elements in the same array at the same time;
Comparison operation (= =,! =) can be performed between two pointers, but the types of the two pointers must be the same;

6) For (p = pbegin; p < pEnd; p + +), p points to the first element of the array. pEnd is considered as an element of the array in C language, so both p and pEnd point to the elements in the same array, which are of the same type and can be compared.

Pointer and array analysis

An array is a contiguous memory space
The space size of the array is sizeof(arr_type) * arr_size
The array name can be regarded as a pointer constant to the first element of the array

1. Pointer operation

Question: what is the meaning of a + 1 for array int a[5]? What is the result? What is the meaning of pointer operation and what is the result?

Conclusion:
Pointer is a special variable. The operation rules between pointer and integer are as follows:
p + n; <--> (unsigned int)p + n * sizeof(*p)
When the pointer p points to an element in an array, p + 1 will point to the next element of the current element; p - 1 will point to the previous element of the current element.

#include <stdio.h>

int main()
{
    int a[5] = {0};
    int* p = NULL;
    
    printf("a = 0x%X\n", (unsigned int)(a));
    printf("a = 0x%X\n", (unsigned int)(a + 1));
    
    printf("p = 0x%X\n", (unsigned int)(p));
    printf("p = 0x%X\n", (unsigned int)(p + 1));
    
    return 0;
}

Output:
a = 0xBFCEEF78
a = 0xBFCEEF7C
p = 0x0
p = 0x4

Only subtraction is supported between pointers; Pointers participating in subtraction must be of the same type:
p1 - p2; <--> ((unsigned int)p1 - (unsigned int)p2) / sizeof(type);
Note: pointer subtraction is meaningful only when two pointers point to elements in the same array. The meaning is the subscript difference of the element pointed to by the pointer; Undefined when the elements pointed to by two pointers are not in the same array

#include <stdio.h>

int main()
{
    char s1[] = {'H', 'e', 'l', 'l', 'o'};
    char s2[] = {'H', 'e', 'l', 'l', 'o'};    
    char* p0 = s1;
    char* p1 = &s1[3];
    char* p2 = s2;
    int i = 0;
    int* p = &i;
    
    
    printf("%d\n", p0 - p1);    // Subscript deviation: - 3
    printf("%d\n", p0 + p2);    // error
    printf("%d\n", p0 - p2);    // undefined behavior
    printf("%d\n", p0 - p);     // error
    printf("%d\n", p0 * p2);    // error
    printf("%d\n", p0 / p1);    // error
    
    return 0;
}
Output: (between pointers)+ * / Are not allowed, and subtraction operations of different types of pointers are not allowed)
test.c:17: error: invalid operands to binary + (have 'char *' and 'char *')
test.c:19: error: invalid operands to binary - (have 'char *' and 'int *')
test.c:20: error: invalid operands to binary * (have 'char *' and 'char *')
test.c:21: error: invalid operands to binary / (have 'char *' and 'char *')

p0 - p2 The output of is 5, but I don't know what that means
#include <stdio.h>

// Calculate the size of the array
#define DIM(a) (sizeof(a) / sizeof(*a))      

int main()
{
    int s1[] = {'H', 'e', 'l', 'l', 'o'};
    int s2[] = {'H', 'e', 'l', 'l', 'o'};    
    int* p0 = s1;
    int* p1 = &s1[3];
    printf("p1 - p0 = %d\n\n", p1 - p0);        // 3


    char s[] = {'H', 'e', 'l', 'l', 'o'};
    char* pBegin = s;
    char* pEnd = s + DIM(s);
    char* p = NULL;
    
    
    printf("pBegin = %p\n", pBegin);
    printf("pEnd = %p\n", pEnd);
    
    printf("Size: %d\n", pEnd - pBegin);    // 5
    
    for (p = pBegin; p < pEnd; p++)         // Pointer comparison
    {
        printf("%C", *p);
    }
    printf("\n");
    
    return 0;
}

Output:
p1 - p0 = 3

pBegin = 0xbf9ff2a7
pEnd = 0xbf9ff2ac
Size: 5
Hello

analysis:

  • char* pEnd = s + DIM(s); pEnd points to the next position of the last element in the array s. Although this position does not belong to the array, in C language, it is still considered that this boundary position belongs to the array. This knowledge point is also applied in STL.
  • For (p = pbegin; p < pEnd; p + +), p points to the first element of the array. pEnd is considered as an element of the array in C language, so both p and pEnd point to the elements in the same array, which are of the same type and can be compared.

2. Pointer comparison

Pointers can also perform relational operations (<, < =, >, > =), but only if they point to elements in the same array at the same time;
Comparison operation (= =,! =) can be performed between two pointers, but the types of the two pointers must be the same;

#include <stdio.h>   

int main()
{
    int a[5] = {0};
    int* p0 = a;
    int* p1 = &a[1];
    char* p2;
    
    
    printf("%d\n", p1 < p0);    // ok, 0
    printf("%d\n", p1 < p2);    // undefined    

    printf("%d\n", p1 != p0);   // ok, 1 
    printf("%d\n", p1 == p2);   // undefined
    
    return 0;
}

The above code has been warned at compile time:
test.c:14: warning: comparison of distinct pointer types lacks a cast
test.c:17: warning: comparison of distinct pointer types lacks a cast

This paper is summarized from the C language advanced course by Tang zuolin, teacher of "Ditai Software College".
Please correct any mistakes and omissions.

Topics: C