一、指针是什么
指针为指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向
(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以
说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址
的内存单元。
在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所
以一个指针变量的大小就应该是4个字节。
那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地
址。
二、指针和指针类型
我们知道变量有整形,浮点型,字符类型等。那么指针是不是也有类型,其实是有的,指针也有不同的类型,且他们都占有四个字节的大小。
那么为了说明下面我们上代码!
```
#include<stdio.h>
int main()
{
int a = 0x11223344;
int* i = &a;
*i = 0;
printf("%d\n", a);
return 0;
}
```
#include<stdio.h>
int main()
{
int a = 0x11223344;
char* i = &a;
*i = 0;
printf("%d\n", a);
return 0;
}
```
这里我们通过调试来查看内存中的变化
第一段代码中我们可以看到内存中a被全部赋为0。
在第二段代码中只有一个字节的内容被覆盖
这也说明了指针有类型,不能混用,且指针类型不同可以操作的的内存大小也不同。
可以说指针类型决定了指针解引用时可以访问几个字节的内容,char*类型可以访问1个字节
int*可以访问4个字节。
接下来我们让指向同一内存的不同类型的指针进行加1,看会发生什么
#include<stdio.h>
int main()
{
int a = 5;
int * p = &a;
char* c = &a;
printf("%p\n", p);
printf("%p\n", c);
printf("%p\n", p+1);
printf("%p\n", c+1);
return 0;
}
这里我们看到p向后跳了4个字节
c条了一个字节。这说明指针类型决定了指针加减整数时会跳过几个字节
三、野指针
3.1野指针的成因
#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; }
3.2如何规避野指针
四、指针运算
这里主要说明指针减指针
#include<stdio.h>
int main()
{
int arr[5] = { 0, 1, 2, 3, 4 };
printf("%d\n",&arr[4]-&arr[0]);
printf("%d\n", &arr[0] - &arr[4]);
return 0;
}
运行结果为
那么可以看出指针减指针为两指针间的元素个数,要注意用高地址减低地址,否则会出现负数。
另外C语言规定允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许 与指向第一个元素之前的那个内存位置的指针进行比较。
五、 指针数组
指针数组是一个数组,其中存放的数据类型1为指针类型,就如int* a[5];棋代表一个a数组其中有五个元素每个元素为int*类型。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a = 5, b = 10, c = 20,i=0;
int* arr[3] = { &a, &b, &c };
for (i = 0; i < 3; i++)
{
printf("%d ", *(arr[i]));
}
return 0;
}
从该程序中可以看到arr[3]中存放了三个地址,再通过解引用就可以得到原值