2

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) is a pointer special variable, integer arithmetic rules:
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) between the pointers only supports subtraction involved in the subtraction must be of the same type:
Note: Only when two pointers point to elements in the same array, pointer subtraction is meaningful, meaning that the subscript difference of the element pointed to by the pointer; when the element pointed to by the two pointers is not in the same array, undefined.
p1 - p2; <--> ((unsigned int)p1 - (unsigned int)p2) / sizeof(type);

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

5) Pointers can also perform relational operations (<, <=, >, >=), but the premise is that points to elements in the same array at the same time;
comparison operations (==,!=) can be performed between two pointers pointers must be the same;

6) for (p = pBegin; p < pEnd ; p++), p points to the first element of the array, pEnd is considered an element of the array in C language, so p and pEnd both point to the same element in the same array, the type is the same , To be able to compare.

Pointer and array analysis

The array is a continuous memory space of
The space size of the array is sizeof(arr_type) * arr_size
The array name can be regarded as pointing to the first element of the array

1. Pointer operation

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

in conclusion:
Pointer is a special variable, with integer arithmetic rule is:
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;
}

输出:
a = 0xBFCEEF78
a = 0xBFCEEF7C
p = 0x0
p = 0x4

between the pointers only supports subtraction involved in the subtraction must be of the same type:
p1 - p2; <--> ((unsigned int)p1 - (unsigned int)p2) / sizeof(type);
Note: Only when two pointers point to elements in the same array, pointer subtraction is meaningful, meaning the subscript difference of the element pointed to by the pointer; when the element pointed to by the two pointers is not in the same array, undefined

#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);    // 下标差:-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;
}
输出:(指针之间的+ * / 都不允许,不同类型指针的减法运算也不允许)
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的输出为5,但并不知道这是什么意思
#include <stdio.h>

// 计算数组的大小
#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++)         // 指针比较,指针运算
    {
        printf("%C", *p);
    }
    printf("\n");
    
    return 0;
}

输出:
p1 - p0 = 3

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

analyze:

  • char* pEnd = s + DIM(s); pEnd points to the position after the last element in array s. Although this position does not belong to the array, is still considered to belong to the array in the C language. 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 an element of the array in C language, so p and pEnd point to the same element in the same array , To be able to compare.

2. Comparison of pointers

Pointers can also perform relational operations (<, <=, >, >=), but the premise is that points to elements in the same array at the same time;
comparison operations (==,!=) can be performed between two pointers 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 article is summarized from "C Language Advanced Course" by Tang Zuolin from "Ditai Software Academy".
If there are any errors or omissions, please correct me.


bryson
169 声望12 粉丝