![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2f83a5fccdba7a75b3e87b28be8bea73.png#pic_center)
指针是什么?
两个要点
- 指针是内存中一个最小单元的编号,也就是地址
- 平时口语中的指针,通常是指针变量,是用来存放内存地址的变量
总结:指针就是地址,口语中的指针是指针变量
- 指针变量是用来存放地址的,地址是唯一标示一块地址空间的
- 指针的大小在32位平台上是4个字节,在64位上是8个字节
X86–>32位环境
X64–>64位环境
地址:0X312FC
0X代表16进制
指针类型
#include <stdio.h>
int main()
{
printf("%zu\n", sizeof(char*)); // 8
printf("%zu\n", sizeof(short*)); // 8
printf("%zu\n", sizeof(int*));// 8
printf("%zu\n", sizeof(float*));// 8
printf("%zu\n", sizeof(double*));// 8
return 0;
}
指针类型的意义:
一:
- 指针类型决定了指针在被解引用的时候访问几个字节
- 如果是int*的指针,解引用访问4个字节
- 如果是char*的指针,解引用访问1个字节
二:
#include <stdio.h>
int main()
{
int a = 10;
int* pa = &a;
char* pc = (char*) & a;
printf("pa=%p\n", pa);
printf("pa+1=%p\n", pa + 1);
printf("pc=%p\n", pc);
printf("pc+1=%p\n", pc + 1);
return 0;
}
观察结果
pa=000000377277FBC4
pa+1=000000377277FBC8
pc=000000377277FBC4
pc+1=000000377277FBC5
- pa是int型,4个字节,±1,地址也随之±4
- pc是char型,1个字节,±1,地址也随之±1
总结:决定了指针的步长
野指针
概念:野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
野指针的成因:
- 指针未初始化
#include <stdio.h>
int main()
{
int* a;//未初始化,没有明确的指向,默认是随机值。
*a = 20;
return 0;
}
- 指针访问越界
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for (i = 0; i <= 10; i++) //循环11次,超出一次
{
*(p++) = i;
}
return 0;
}
- 指针指向的空间释放
这里放在动态内存开辟方面会讲,简单提示一下
#include <stdio.h>
int* test()
{
int a = 10;
return &a;
}
int main()
{
int* p = test();
return 0;
}
a是在test()函数内创建的局部变量,出了该函数就销毁了,所以p无法接收
但是
如果其p存储的变量没有定向,直接printf输出是可以输出a的值
但是
如果printf输出p的前面有printf,则输出的p的值就是随机的
如何避免野指针
- 指针初始化
- 小心指针越界
- 指针指向空间释放及时置NULL
- 避免返回局部变量的地址
- 指针使用之前检查有效性
空指针
#include <stdio.h>
int main()
{
int* p = NULL;
if (p)
{
*p = 100;
}
return 0;
}
这里创建一个空指针,判断是否有指定地址,有的话直接对其进行赋值
指针的使用
指针±整数
例题:元素为0的数组,元素值改为1
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
int i = 0;
for (i = 0; i < sz; i++)
{
*(p + i) = 1;
}
return 0;
}
*p++=0:先对指针变量p=0进行操作,在对p++
(*p)++:直接对p地址进行++
指针-指针
|指针-指针|(绝对值)得到的是:
指针和指针之间的元素个数
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("%d\n", &arr[9] - &arr[0]);
return 0;
}
输出结果:
9
注:指向同一块区域的指针才能相减
再次示例:自定义函数求其字符串长度
#include <stdio.h>
int my_strlen( char* str)
{
char* start = str;
while (*str != '\0')
{
str++;
}
return (str - start);
}
int main()
{
int len = my_strlen("abcdef");
printf("%d\n", len);
return 0;
}
运行结果:6
标准规定
允许数组元素的指针与指向数组最后一个元素后面的内存位置上的指针相比较,不允许与其前面的比较
如图:p1可与p2比较,不可与p3比较
指针收尾
二级指针
-----------------------数组与指针-----------------------------
- arr[i]–>*(arr+i)
指针数组
概念:存放指针的数组
#include <stdio.h>
int main()
{
int a = 10, b = 20, c = 30;
int* pa = &a;
int* pb = &b;
int* pc = &c;
int* paar[10] = { &a,&b,&c };
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%d ", *(paar[i]));
}
return 0;
}
10 20 30
指针和二维数组
#include <stdio.h>
int main()
{
int arr1[4] = { 1,2,3,4 };
int arr2[4] = { 2,3,4,5 };
int arr3[4] = { 3,4,5,6 };
int* paar[3] = { arr1,arr2,arr3 };
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%d ", paar[i][j]);
}
printf("\n");
}
return 0;
}
1 2 3 4
2 3 4 5
3 4 5 6