0602 - pointers and arrays

array name

The array name is an address constant, assignment is not allowed. It represents the address of the first element of the array.

Pointer manipulation of array elements

pointer access array

指针类型变量\常量+1Equivalent to 指针保存的内存地址+sizeof(指针指向的数据类型).

When two pointers of the same type are subtracted, the result is the offset of the two pointers. The offset unit (also called the step size) is sizeof(指针指向的数据类型).

#include<stdio.h>

int main() {
    
    
	int arr[] = {
    
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	int* p = arr;
	int length = sizeof(arr) / sizeof(int);

	for (size_t i = 0; i < length; i++)
	{
    
    
		printf("arr[%d]=%d, p[%d]=%d, *(arr+%d)=%d, *(p+%d)=%d\n", 
			i, arr[i], i, p[i], i, *(arr+i), i, *(p+i));
	}

	int* q = arr;
	for (size_t i = 0; i < length; i++)
	{
    
    
		printf("第%d项=%d\n", i, *q);
		q++;
	}

	/*
	下面计算得出,q与arr的偏移量为10(个步长)
	*/
	int step = q - arr;
	printf("step=%d\n", step);
	return 0;
}

Run the above code, the result is as follows:
insert image description here
PS: It is recommended to use the pointer to operate the array p[i], because p[i]it is *(p+i)simpler and clearer.
[i]Equivalent to offset + value, p[i]it means to pstart from the saved address, offset by i steps and take the value.

Difference between array name and pointer

1. The array name is a constant, and the pointer is a variable;
2. sizeofThe results are different;

#include<stdio.h>

int main() {
    
    
	int arr[] = {
    
     1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* p = arr;

	printf("sizeof(arr) = %u\n", sizeof(arr));
	printf("sizeof(p) = %u\n", sizeof(p));
	return 0;
}

Execute the above code, the result is as follows:
insert image description here

Array name degenerates

When an array is used as a function parameter, the array name degenerates into a pointer variable, and the array length is lost.

#include<stdio.h>

/*
printArrayLen(int arr[])等价于printArrayLen(int* arr)
*/
void printArrayLen(int arr[]) {
    
    
	int len = sizeof(arr) / sizeof(arr[0]);
	printf("参数数组的长度:%d\n", len);
	/*
	* 数组作为函数参数时,数组名退化为指针,
	* 所以此处arr相当于指针变量。
	*/
	printf("sizeof(arr) = %d\n", sizeof(arr));

}

int main() {
    
    
	int a[10] = {
    
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	printArrayLen(a);
	return 0;
}

Run the above code, the result is as follows:
insert image description here

pointer addition and subtraction

The step size of pointer auto-increment or auto-decrement is only related to the data type pointed by the pointer, and has nothing to do with the data type actually assigned to the pointer variable.

#include<stdio.h>

int main() {
    
    
	int arr[] = {
    
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	//给p和p2赋上相同的值
	int* p = &arr[9];
	char* p2 = &arr[9];
	printf("p保存的地址:%p\n", p);
	printf("p2保存的地址:%p\n", p2);

	p--;
	p--;
	p--;
	p2--;
	p2--;
	p2--;
	//p自减的步长为4字节,p2自减的步长为1字节
	printf("\"p--\"3次后, p保存的地址:%p\n", p);
	printf("\"p2--\"3次后, p2保存的地址:%p\n", p2);
}

Run the above code, the result is as follows:
insert image description here
pointer operators only support "addition and subtraction of pointers and integers", "subtraction of pointers of the same type", "ratio of two pointers", "logical operators", and other pointer operations are meaningless.

array of pointers

An array of pointers is an array in which each element is a pointer type.

#include<stdio.h>

void main() {
    
    
	int a = 10;
	int b = 20;
	int c = 30;

	int* arr[3] = {
    
    &a, &b, &c};

	printf("a = %d\n", *arr[0]);
	return 0;
}

Run the above code, the result is as follows:
insert image description here
the pointer array is equivalent to a two-dimensional array.

#include<stdio.h>

void main() {
    
    

	int a[] = {
    
     1, 2, 3 };
	int b[] = {
    
     4, 5, 6 };
	int c[] = {
    
     7, 8, 9 };

	int* d[] = {
    
    a, b, c};

	for (int i = 0; i < sizeof(d) / sizeof(d[0]); i++) {
    
    
		printf("%d %d %d\n", *d[i], *(d[i]+1), *(d[i]+2));
	}
	printf("=====\n");
	for (int i = 0; i < sizeof(d) / sizeof(d[0]); i++) {
    
    
		printf("%d %d %d\n", d[i][0], d[i][1], d[i][2]);
	}
	printf("=====\n");
	for (int i = 0; i < sizeof(d) / sizeof(d[0]); i++) {
    
    
		printf("%d %d %d\n", (*(d+i))[0], (*(d + i))[1], (*(d + i))[2]);
	}
}

Run the above code, the result is as follows:
insert image description here

multilevel pointer

#include<stdio.h>

int main() {
    
    

	int a[] = {
    
    1, 2, 3};
	int b[] = {
    
    4, 5, 6};
	int c[] = {
    
    7, 8, 9};

	int* arr[] = {
    
    a, b, c};
	/*
	p保存的是&(int*),也就是int*型变量的地址,而不是int*型变量的值
	arr是数组首元素a的地址,而a类型是int*,所以arr是int*的地址。
	所以可以将arr赋值给p。

	从而指针数组和二级指针建立关系。
	二级指针指向指针数组的首元素。
	*/
	int** p = arr;

	printf("p最终指向的整形为:%d\n", **p);
	printf("*p = %p\n", *p);
	printf("数组a的首地址=%p\n", a);
	printf(" *(p+1) = %p\n", *(p+1));
	printf("数组b的首地址=%p\n", b);
	printf(" *(p+2) = %p\n", *(p + 2));
	printf("数组c的首地址=%p\n", c);

	printf("====遍历指针数组====\n");
	for (int i = 0; i < 3; i++) {
    
    
		for (int j = 0; j < 3; j++) {
    
    
			//下面三行代码等价
			printf("%d ", p[i][j]);
			//printf("%d ", *(p[i]+j));
			//printf("%d ", *(*(p + i) + j));
		}
		printf("\n");
	}
	return 0;
}

Run the above code, the result is as follows
insert image description here

#include<stdio.h>

int main() {
    
    
	int a = 10;
	int b = 20;
	int* p = &a;
	int** pp = &p;

	//下面2行代码输出“*p = 20”
	//*pp = &b;
	//printf("*p = %d\n", *p);


	//下面3行代码输出
	//*p = 30
	//a = 30
	**pp = 30;
	printf("*p = %d\n", *p);
	printf("a = %d\n", a);
	return 0;
}
int main() {
    
    
	int a = 10;
	int* p = &a;
	int** pp = &p;
	int*** ppp = &pp;

	//下列等式成立
	//*ppp == pp == &p
	//**ppp == *pp == p == &a
	//***ppp == **pp == *p == a
}

Guess you like

Origin blog.csdn.net/jiejingguo/article/details/130804327