先来简单的了解指针
可以说地址即是指针
通过指针(地址)能找到以它为地址的内存单元
存放于指针中的值都被当成地址处理
一个简单的指针
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);
}
这样我们就很清楚的看到类型的作用:
即指针类型决定指针解引用能够访问空间的大小
不妨测试下:
指针变量的大小都一样 主要是访问空间的大小不同
//64位机器上 一个指针变量大小为8个字节
//32位机器上 一个指针变量大小为4个字节
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(float *));
常用的:
- int 4个字节
- char 1个字节
- double 8个字节
- 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]);
}
可以看到改为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);
标签:10,arr,初阶,48,int,C语言,char,printf,指针
From: https://www.cnblogs.com/gaodiyuanjin/p/18211597