本节我们要介绍的是
1.指针是什么
2.指针与指针类型
3.野指针
4.指针运算
5.指针与数组
6.二级指针
1.什么是指针
与其给出指针的定义,看完让人模糊不清,不如给出下面几个通俗易懂的要点。
- 编号是如何产生的呢?
- 我们一个内存单元该是多大呢?
int main()
{
int a = 10;
int* p = &a;//p是指针变量,存放a的地址,类型是int*
return 0;
}
一个指针占几个字节,等于是一个地址的内存单元编号有多长。
32位机器上,一个字节八个bit位,32bit/8bit=4个字节,所以32位要4个字节来存储地址,64位需要8个字节存储地址,
注意,地址是不占用内存空间的,可以根据它的由来看出,它是地址线形成的,不需要专门的内存来存储这些地址,
2.指针与指针类型
指针类型的大小都是4,那指针类型有什么意义呢?
int main()
{
int a = 0x11223344;
int* pa = &a;
char* pc = &a;
printf("%p\n", pa);
printf("%p\n", pc);
return 0;
}
上面的代码很显然指针变量pa pc都能很好的存放a的地址,打印出来地址也都是一样的,是否说明指针类型更没有用呢?
int main()
{
int a = 0X11223344;
int* pa = &a;
*pa = 0;
return 0;
}
写入上述代码,按住F10,进入调试界面,
按下面三步走,
可以看到 ,地址a的空间确实存了我们的数据
*pa=0,说明我们把内存a的数据变成了0,
有了上述测试的方法,我们把下面代码按照上述过程再来一把
int main()
{
int a = 0X11223344;
char* pc = &a;
*pc = 0;
return 0;
}
最后现象如下图所示,可以看出,只改了一个字节大小,
通过上面两次的测试,我们明白了指针类型的重要性,
存储数据时,所以类型都可以容纳,
但是一旦要解引用操作时,指针类型决定了指针进行解引用操作时,能够访问空间的大小
int*p *p 能够访问四个字节空间
char*p *p 能够访问1个字节空间
double*p *p 能够访问8个字节空间
指针+-整数
写入以下代码
#include <stdio.h>
//演示实例
int main()
{
int n = 0x11223344;
char* pc = &n;
int* pa = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc + 1);
printf("%p\n", pa);
printf("%p\n", pa + 1);
return 0;
}
运行结果如下:
总结:指针的类型决定了指针向前或者向后走一步有多大(距离)
具体应用可以看下面的代码(实现的效果是把数组的元素全部改为1)打开监视可以看到相应的数变化情况,而用char *p=arr则不行。
int main()
{
int arr[10] = { 0 };
int* p = arr;//数组名,首元素地址
int i = 0;
for (i = 0 ;i < 10; i++)
{
*(p + i) = 1;
}
return 0;
}
野指针
int* p;//局部的指针变量,就被初始化为随机值
#include <stdio.h>
int main()
{
int *p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
#include <stdio.h>
int main()
{
int arr[10] = {0};
int *p = arr;
int i = 0;
for(i=0; i<=11; i++)
{
//当指针指向的范围超出数组arr的范围时,p就是野指针
*(p++) = i;
}
return 0;
}
int* test()
{
int a = 10;
return &a;
}
int main()
{
int* p = test();
*p = 20;
return 0;
}