指针与数组、多级指针

指针和数组:

数组名:
【数组名是地址常量】 --- 不可以被赋值。 ++ / -- / += / -= / %= / /= (带有副作用的运算符)

指针是变量。可以用数组名给指针赋值。 ++ --

取数组元素:

int arr[] = {1,3, 5, 7, 8};

int *p = arr;

arr[i] == *(arr+0) == p[0] == *(p+0)

指针和数组区别:

1. 指针是变量。数组名为常量。

2. sizeof(指针) ===》 4字节 / 8字节

sizeof(数组) ===》 数组的实际字节数。

指针++ 操作数组:

image

int arr[] = { 1, 2, 4, 5, 6, 7, 8, 9, 0 };
int *p = arr;

for (size_t i = 0; i < n; i++)
{
printf("%d ", *p);
p++; // p = p+1; 一次加过一个int大小。 一个元素。
}

p的值会随着循环不断变化。打印结束后,p指向一块无效地址空间(野指针)。

指针加减运算:
image

数据类型对指针的作用:

1)间接引用:

决定了从指针存储的地址开始,向后读取的字节数。 (与指针本身存储空间无关。)

2)加减运算:

决定了指针进行 +1/-1 操作向后加过的 字节数。

指针 * / % : error!!!

指针 +- 整数:

1) 普通指针变量+-整数

char *p; 打印 p 、 p+1 偏过 1 字节。

short*p; 打印 p 、 p+1 偏过 2 字节。

int *p; 打印 p 、 p+1 偏过 4 字节。

2)在数组中+- 整数

short arr[] = {1, 3, 5, 8};

int *p = arr;

p+3; // 向右(后)偏过 3 个元素

p-2; // 向前(左)偏过 2 个元素

3)&数组名 + 1

加过一个 数组的大小(数组元素个数 x sizeof(数组元素类型))

指针 +- 指针:

指针 + 指针: error!!!

指针 - 指针:

1) 普通变量来说, 语法允许。无实际意义。【了解】

2) 数组来说:偏移过的元素个数。

指针实现 strlen 函数:

char str[] = "hello";

char *p = str;

while (*p != '\0')
{
p++;
}

p-str; 即为 数组有效元素的个数。

指针比较运算:

1) 普通变量来说, 语法允许。无实际意义。

2) 数组来说: 地址之间可以进行比较大小。

可以得到,元素存储的先后顺序。

3) int *p;

p = NULL; // 这两行等价于: int *p = NULL;

if (p != NULL)

printf(" p is not NULL");

else
printf(" p is NULL");

指针数组:

一个存储地址的数组。数组内部所有元素都是地址。

1)
int a = 10;
int b = 20;
int c = 30;

int *arr[] = {&a, &b, &c}; // 数组元素为 整型变量 地址
2)

int a[] = { 10 };
int b[] = { 20 };
int c[] = { 30 };

int *arr[] = { a, b, c }; // 数组元素为 数组 地址。

指针数组本质,是一个二级指针。

二维数组, 也是一个二级指针。

image

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

// 指针数组1
int main0901(void)
{
	int a = 10;
	int b = 20;
	int c = 30;

	int *p1 = &a;
	int *p2 = &b;
	int *p3 = &c;

	int *arr[] = {p1, p2, p3};  // 整型指针数组arr, 存的都是整型地址。

	printf("*(arr[0]) = %d\n", *(*(arr + 0)));  //arr[0] ==  *(arr+0)

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

	system("pause");
	return EXIT_SUCCESS;
}
// 指针数组2
int main0902(void)
{
	int a[] = { 10 };
	int b[] = { 20 };
	int c[] = { 30 };

	int *arr[] = { a, b, c };  // 整型指针数组arr, 存的都是整型地址。

	printf("*(arr[0]) = %d\n", *(*(arr + 0)));  //arr[0] ==  *(arr+0)

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

	system("pause");
	return EXIT_SUCCESS;
}

多级指针:

int a = 0;

int *p = &a; 一级指针是 变量的地址。

int **pp = &p; 二级指针是 一级指针的地址。

int ***ppp = &pp; 三级指针是 二级指针的地址。

int ****pppp = &ppp; 四级指针是 三级指针的地址。 【了解】
......

多级指针,不能 跳跃定义!

对应关系:

ppp == &pp; 三级指针

*ppp == pp == &p; 二级指针

**ppp == *pp == p == &a 一级指针

***ppp == **pp == *p == a 普通整型变量

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

int main1001(void)
{
	int a = 10;
	int *p = &a;
	int **pp = &p;
	// int **pp = &(&a); ²»ÔÊÐí£¡£¡
	int ***ppp = &pp;

	printf("***ppp = %d\n", ***ppp);
	printf("**pp = %d\n", **pp);
	printf("*p = %d\n", *p);
	printf("a = %d\n", a);

	system("pause");
	return EXIT_SUCCESS;
}

*p : 将p变量的内容取出,当成地址看待,找到该地址对应的内存空间。

如果做左值: 存数据到空间中。

如果做右值: 取出空间中的内容。

posted @ 2023-03-03 14:48  zggb  阅读(69)  评论(0)    收藏  举报