数组名与指针的关系
数组名本质上是数组首元素的指针常量,其存储的地址不可修改。
类型差异
- int a[50] 声明数组
- int *p 声明指针
sizeof运算差异
int a[50];
sizeof(a); // 返回整个数组大小:sizeof(int)*50
int *p;
sizeof(p); // 返回指针变量大小(64位系统通常为8字节)
指针与数组的等价性
在大多数表达式中,数组名会自动转换为指向首元素的指针:
int a[10];
int *p = a; // 合法,数组名a转换为指针
数组访问的等价形式:a[i] 等价于 *(a + i)
指针算术与数组访问
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // 指向数组首元素
// 通过指针访问数组元素
for(int i = 0; i < 5; i++) {
printf("%d ", *(ptr + i)); // 等价于ptr[i]
}
多维数组与指针
对于二维数组:
int matrix[3][4];
- matrix类型是int (*)[4]
- matrix[0]类型是int [4]
- &matrix[0][0]类型是int *
函数参数传递
void printArray(int *arr, int size) {
for(int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
}
int main() {
int a[5] = {1, 2, 3, 4, 5};
printArray(a, 5); // 数组名作为指针传递
return 0;
}
使用指针访问数组元素
int a[5]={1,2,3,4,5}; // 声明并初始化数组
// 打印地址信息
printf("array addr %p\\n", a); // 等价于&a[0]
printf("a[0] %p\\n", &a[0]);
printf("a[1] %p\\n", &a[1]); // 地址比a[0]大sizeof(int)
int *p = a; // 指针指向数组首地址
// 四种等效访问方式
printf("a[0] %d\\n", a[0]); // 数组下标
printf("*(p+0) %d\\n", *(p+0)); // 指针算术
printf("*(a+0) %d\\n", *(a+0)); // 数组名作为指针
printf("p[0] %d\\n", p[0]); // 指针下标语法
// 地址一致性验证
printf("a[0] addr %p\\n", &a[0]);
printf("*(p+0) addr %p\\n", &(*(p+0)));
printf("*(a+0) addr %p\\n", &(*(a+0)));
printf("p[0] addr %p\\n", &p[0]);
// 访问第二个元素
printf("a[1] %d\\n", a[1]);
printf("*(p+1) %d\\n", *(p+1));
函数参数传递方式
值传递
- 形参是实参的副本
- 只能读取实参数据
- 修改形参不影响实参
- 适用于基本类型和构造类型变量
地址传递
- 形参接收实参的内存地址
- 可通过地址直接修改实参指向的内容
数组名与指针访问注意事项
int main() {
char str[100] = "hello";
char* p = str;
/*
while(*p) {
printf("%c", *p);
p++; // 允许指针递增
}
*/
/*
while(str) {
printf("%c", *str);
str++; // 错误:数组名是常量指针
}
*/
show(str);
}
指针函数与函数指针
指针函数(返回指针的函数)
注意事项:
- 不要返回局部变量的地址
int* fun() {
int a = 20;
return &a; // 错误:局部变量会被释放
}
int main() {
int* p = fun();
printf("ret = %d\\n", *p); // 访问已释放内存
return 0;
}
- 使用static变量
char* fun2() {
static char str[100] = "hello"; // 具有全局生命周期
return str;
}
int main() {
char* p = fun2();
printf("p: %s\\n", p);
return 0;
}
- 返回字符串常量
char* fun3() {
char* p = "hello"; // 字符串常量存储在数据区
return p;
}
int main() {
char* p = fun3();
printf("p: %s\\n", p);
return 0;
}
指针操作示例
#include <stdio.h>
int main() {
char str[100] = "hello";
char* p = str; // 指针指向数组首地址
*p = 'a'; // 通过指针修改首字符
printf("%s\\n", p); // 输出: aello
printf("%s\\n", str); // 输出: aello
return 0;
}




