一、指针是什么?
①指针是地址;
②口语中的指针指的是指针变量,它是用来存储一个变量所在的地址。
二、地址是什么?
说到地址,那么需要了解内存的知识。程序运行前,数据会先放到内存才能被CPU处理,内存跟我们日常生活里的酒店一样,每个房间都住着人,如何通过房间找到我们要找的人,就需要给每个房子加上编号,通过编号我们就能知道该编号里有什么人,内存我们可以理解如下的图片。
内存里面也被划分为多个小房间,每个小房间就是一个存储单元(比如字节就是最小的存储单元),旁边的数字就是编号也就是地址,不过在VS中,这个地址通常以16进制(例如0x0000000001)来表示。
三、指针的大小
在32位的机器上,指针大小为4个字节(一个字节等于八个位)
在64位的机器上,指针大小位8个字节
四、入门的指针代码
#include <stdio.h>
int main()
{
int a = 10;//在内存里开辟了一个空间
int* p = &a;//“&”这个符号表示的是取出变量a的地址
//p是一个指针变量,因为指针大小为4个字节,这里是把a的第一个字节的地址放在p变量中
*p = 5;
//“*”这个符号叫解引用,通过这个符号,我们可以获取a地址上的值并且更改它
//注意:int* 是类型,这里的*不是解引用
printf("%d",a);//a被改为了5,这里的a换成*p是一个结果
return 0;
}
五、指针的类型
在学习C语言的时候,我们会遇到很多的类型例如int,float,char等,同理指针变量也会有它们自己的类型,其实跟普通变量差不多就是在后面加个“*”号,例如int*,char*等。拿int*做例子,意思是:int*类型的指针是为了存放int类型变量的地址。其余类型也是如此。
那么指针类型是占几个字节呢?我们可以看如下的代码
#include <stdio.h>
int main()
{
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(char*));
printf("%d\n", sizeof(short*));
printf("%d\n", sizeof(double*));
}
如果你运行代码的话,你会发现的它们的值是一样的,有些人是4有些人是8位,这跟你们的编程环境有关,有些人是64位的,那么就显示8。有些人是32位,那么就显示4。既然大小一样那又有什么意义?指针类型的类型不同代表指针解引用的时候,能访问空间的大小,它能走多远。我们可以看如下的代码。
#include <stdio.h>
int main()
{
int a = 0x11223344;//四个字节
int* pa = &a;
*pa = 0;// a从0x11223344变成0x00000000
/*上下两行代码请分别使用,这里只是为了告诉结果*/
char* pa = &a;
*pa = 0;// a从0x11223344变成0x11223300
}
由此我们可以得出以下规律
int* p/float* p *p能访问四个字节
char* p *p能访问一个字节
double* p *p能访问八个字节
六、指针的加减
演示代码如下
#include <stdio.h>
int main()
{
int n = 10;
char* pc = (char*)&n; //把整型变量n的地址强制转换成char*
int* pi = &n;
printf("&n: %p\n", &n);
printf("pc: %p\n", pc);
printf("pc+1:%p\n", pc + 1);
printf("pi: %p\n", pi);
printf("pi+1:%p\n", pi + 1);
return 0;
}
演示结果如下
我们只需关注后两位,可以发现char*指针走了1步,而int*指针走了四步。因此指针类型的不同代表了它能走多远。
七、野指针
野指针的成因(不完全)如下
①未初始化
#include <stdio.h>
int main()
{
int *p;//这里没有初始化,默认为随机值
*p = 20;
return 0;
}
②越界访问
#include <stdio.h>
int main()
{
int i = 0;
int arr[10]={0};
int *p = arr;
for(i=0;i<=11;i++)
{
*(p++) = i;//数组里面只有10个元素,但for循环却要循环11次,因此越界,此时的p就是野指针
}
return 0;
}
八、 指针和数组
结论:数组名表示的是数组首元素的地址
通过指针访问数组的代码如下
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* p = arr;
for ( i = 0; i < sz; i++)
{
printf("%d ", *(p++));//p++先使用再加加
}
return 0;
}
九、二级指针
我们所说的指针是指针变量,它也是变量,是变量就会有自己的地址,那么存储指针变量地址的指针就是二级指针,以代码表示如下
#include <stdio.h>
int main()
{
int a = 10;
int* pa = &a;
int** ppa = &pa;//ppa就是二级指针,它存储了pa的地址
**ppa = 30;
printf("%d",a);//a就是30
return 0;
}