目录
一、指针和数组的区别(数组名只是一个地址,而指针是一个左值)
在C语言中,指针和数组在某些情况下可以互换使用,但它们之间存在一些基本的区别:
- 数组名:数组名是一个常量,不能被修改来指向其他内存位置。数组名代表数组的首地址,即数组第一个元素的内存地址。。
- 指针:指针是一个变量,它可以被赋值为任何有效的内存地址。指针可以被修改,指向不同的内存位置,这是它与数组名的主要区别。
二、指针数组
指针数组的本质是数组,其元素都是指针。这种数据结构常用于管理多个字符串或多个内存地址。以下是两个示例,展示了指针数组的使用方法。
1. ** 使用指针数组存储多个地址**
相当于存储了多个指针的数组
#include <stdio.h>
int main() {
int a = 1;
int b = 2;
int c = 3;
int *p[] = {&a, &b, &c};
for (int i = 0; i < 3; i++) {
printf("%d\n", *p[i]); // 通过指针数组访问并打印每个整数的值
}
return 0;
}
- 运行结果及代码可视化:
基于以上用法,我们可以想到下面的用法
2. ** 使用指针数组定义多个字符串(常用)**
#include <stdio.h>
int main() {
char *p[] = {
"数组名是一个地址",
",",
"而指针是一个左值"
};
char str[] = "以上为指针和数组的区别";
for (int i = 0; i < 3; i++) {
printf("%s", p[i]); // 打印指针数组中的每个字符串
}
printf("\n%s\n", str); // 打印另一个字符串
return 0;
}
- 运行结果及代码可视化:
请自行放大观看
三、数组指针(指向数组的指针)
数组指针的本质是指针。它指向数组的首地址,可以通过计算来指向其他的元素(计算方式类似于数组),因此可以认为它是指向数组中元素地址的指针,因为指向的是地址,所以在取值操作时时要使用两次取值操作符“*”
(这里不理解的可以看看文末“ 四、数组指针和数组元素的关系”的代码)。
#include <stdio.h>
int main() {
int temp[5] = {1, 2, 3, 4, 5};
// p2 指向整个数组 temp
int (*p2)[5] = &temp; // 也可以写作temp,因为:数组的地址=数组首元素的地址
for (int i = 0; i < 5; i++) {
printf("%d\n", *(*p2 + i)); // 表示 数组的地址 + i * sizeof(int),然后再取值
}
return 0;
}
p2
是一个指向包含5个整数的一维数组的指针。这里的偏移量就是i * sizeof(int)
,即i
个int
类型所占内存的大小
- 运行结果及代码可视化:
四、数组指针和数组元素的关系
#include <stdio.h>
int main() {
int temp[5] = {1, 2, 3, 4, 5};
int (*p2)[5] = &temp;
for (int i = 0; i < 5; i++) {
printf("*p2+%d: %p\n", i, *p2 + i); // 打印通过数组指针计算得到的地址
printf("&temp[%d]: %p\n", i, &temp[i]); // 打印数组元素的实际地址
}
return 0;
}
- 运行结果及代码可视化:
由此,我们可以更清晰地认识数组指针指向的是数组首元素的地址,数组中其他元素的地址可以由首地址计算得出