欢迎光临
我们一直在努力

数组名与指针的奥秘

数组名与指针的关系

数组名本质上是数组首元素的指针常量,其存储的地址不可修改。

类型差异

  • 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;
}

赞(0)
未经允许不得转载:171主机测评 » 数组名与指针的奥秘
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址