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.