先来简单的了解指针

image

可以说地址即是指针
通过指针(地址)能找到以它为地址的内存单元
存放于指针中的值都被当成地址处理

一个简单的指针
int a=10;
int* p=&a;
int a = 1;
int *pa = &a;
char *pc = &a;
//取出地址一样
printf("%p\n", pa);
printf("%p\n", pc);

那既然输出的地址一样 那还区分char和int类型干嘛

#include<stdio.h>
int main() {
int a = 0;
int *pa = &a;
char *pc = &a;
printf("%p\n", pa);
printf("%p\n", pa + 1);
printf("%p\n", pc);
printf("%p\n", pc + 1);
}

image

这样我们就很清楚的看到类型的作用:
即指针类型决定指针解引用能够访问空间的大小
不妨测试下:

指针变量的大小都一样 主要是访问空间的大小不同
//64位机器上 一个指针变量大小为8个字节
//32位机器上 一个指针变量大小为4个字节
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(float *));

常用的:

  1. int 4个字节
  2. char 1个字节
  3. double 8个字节
  4. float 8个字节

再看具体例子:

int arr[10] = {0};
//数组名为数组首元素的地址
int *p = arr;
//若改成char 只修改了总共10个字节
// char *p=arr;
int i = 0;
for (i = 0; i < 10; ++i) {
*(p + i) = 1;
}
for (int i = 0; i < 10; ++i) {
printf("%p\n", arr[i]);
}

image

image

可以看到改为char*后只能 向后修改10个字节 因为char类型的作用


野指针

简单来说就是指针指向位置是不可知的 就是瞎**乱指
三种情况:

#include<stdio.h>
int *fun();
static int b;
int a;
float c;
int main() {
//指针不初始化 就是一个随机值 野指针
int *p;
printf("%d\n", a);
printf("%d\n", b);
printf("%f\n", c);
printf("%p\n", p);
//指针越界访问 野指针
int arr[10] = {0};
int *pp = arr;
int i = 0;
for (i = 0; i < 12; ++i) {
*pp + 1;
}
//指针指向了已经释放的内存空间 野指针
int *ppp = fun();
*ppp=20;
}
int *fun() {
int a = 10;
return &a;
}

如果要避免就对应上述三种情况避免 就是规范写法


指针的运算:

  • 指针+-整数
  • 指针-指针
  • 指针的关系运算(比较大小)

这里穿插个知识 随着下标增大 对应地址也变大

//打印数组
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int n = sizeof(arr) / sizeof(arr[0]);
int *p = arr;
for (int i = 0; i < n; ++i) {
printf("%d ", *p);
//指针p+1
*p += 1;
}
#include<stdio.h>
#define value 5
int main() {
//将数组values元素全赋值为0
float values[value];
float *vp;
for (vp = &values[0]; vp < &values[value];) {
//分号";"后没有vp++ ====》先算赋值运算 然后vp++
*vp++ = 0;
}
printf("\n%d\n", *vp);
}
#include<stdio.h>
int main() {
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//得到的是中间元素个数
printf("%d", &a[9] - &a[0]);
}
规定比较只可与最后一个元素之后进行比较

指针和数组

还是要说到关于数组名首元素地址的问题:

//关于元素首地址
int arr[10] = {0};
printf("%p\n", arr);
//加了4
printf("%p\n", arr + 1);
printf("%p\n", &arr[0]);
//加了4
printf("%p\n", &arr[0] + 1);
//&arr整个数组的地址
printf("%p\n", &arr);
//加了40 跨过了一个数组
printf("%p\n", &arr + 1);
就两个例外: 1. &arr 取出整个数组地址 2.sizeof(arr) 表示整个数组大小
//指针数组 存放指针的数组
int x = 10, y = 20, c = 30;
int* ok[3]={&x,&y,&c};
for (int i = 0; i < 3; ++i) {
printf("%d ",*(ok[i]));

二级指针
int* pa : *pa告诉是个指针 int 告诉指向对象类型为int
int a = 10;
int *p = &a;
int **p2 = &p;
printf("%d\n", **p2);
**p2 = 50;
printf("%d\n", a);
posted on   不爱美女爱辣条  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?



点击右上角即可分享
微信分享提示