目录
一:为什么要学习指针
变量名(定义) ---》 地址(内存) ---》 数据(获取读取)
按值传递:函数内部改变,函数外部不变,示例如下
#include<stdio.h>
void swap(int a,int b)//按地址传递
{
int temp=0;
temp=a;
a=b;
b=temp;
}
int main()
{
int a=3,b=4;
printf("交换前a=%d,b=%d\n",a,b);//a=3,b=4
swap(a,b);
printf("交换后a=%d,b=%d\n",a,b);//a=3,b=4
return 0;
}
为了能够实现数据传递 不局部不消亡,需要学习按地址传递,也就是指针
二:按地址传递 [指针]
指针定义:指针是用来描述地址的数据类型
如下示例: a是int类型的指针变量
#include<stdio.h>
void swap(int *a,int *b)//按地址传递
{
int temp=0;
temp=*a; //地址取值
*a=*b;
*b=temp;
}
int main()
{
int a=3,b=4;
printf("交换前a=%d,b=%d\n",a,b);//a=3,b=4
swap(&a,&b); //传入了地址
printf("交换后a=%d,b=%d\n",a,b);//a=4,b=3
return 0;
}
三:指针变量
指针变量:存储A的地址,通过A的地址,去访问获取A的数据
如下示例:
指针变量p存放变量a的地址,获取读取变量a的数据【指针变量:存储别人的地址】
#include<stdio.h>
void swap(int *a,int *b)//按地址传递
{
int temp=0;
temp=*a; //地址取值
*a=*b;
*b=temp;
}
int main()
{
int a=1;
//指针变量 (存储别人的地址)
int *p=&a;//指针变量的定义及初始化
printf("a的地址是:%p\n",&a); //0019FF2C
printf("指针变量p的地址是:%p\n",p);//0019FF2C(存储别人的地址)
return 0;
}
四:指针变量的定义
指针变量定义,需要初始化
指针变量一般初始化为NULL 0强制转换为void*
#include<stdio.h>
int main()
{
//指针变量 存储地址
int *p=NULL;//指针变量的定义及初始化
printf("指针变量p的地址是:%p\n",p);//00000000
return 0;
}
五:野指针
指针变量定义 记得需要初始化,否则会野指针(危险操作),示例如下
#include<stdio.h>
int main()
{
int a=3,b=4;
//野指针 程序异常结束
int *pa; //野指针 随便指
int *p=NULL;//指针变量 初始化NULL
printf("指针变量pa的地址是:%p\n",pa);//CCCCCCCC
return 0;
}
因此指针变量定义后 一定要记得初始化NULL
六:指针的定义
指针的定义(2种方式)
1.定义初始化指针变量NULL后,再赋初值
2.定义指针变量同时直接赋初值
1.定义初始化指针变量,后赋初值
#include<stdio.h>
int main()
{
int a=3,b=4;
int *p=NULL;//定义1 定义并赋初值
p=&a;
printf("指针变量p的地址是:%p\n",p);//0019FF2C
printf("指针变量p的值是:%d\n",*p);//3 *取值
return 0;
}
2.定义指针变量同时直接赋初值
#include<stdio.h>
int main()
{
int a=3,b=4;
int *pb=&b; //定义2 定义赋值
printf("指针变量pb的地址是:%p\n",pb);//0019FF28
printf("指针变量pb的值是:%d\n",*pb);//4
return 0;
}
七:指针 & 指针变量
一个变量的地址称为该变量的“指针”,指针就是地址,用来描述地址
如:int * ptr // ptr是int类型的指针变量
指针变量:专门用来存放另一个变量的地址
指针变量也是变量,指针变量存储的是别人的地址,*代表取值
变量都有地址,因此指针变量也有地址
#include<stdio.h>
int main()
{
int a=3,b=4;
int *p=NULL;//定义1 定义并赋初值
p=&a;
printf("%p\n",&p);//0019FF24 指针变量是变量 变量就有地址(p的地址)
printf("%p\n",*&p);//0019FF2C 指针变量取值也用* 取到的值是个地址(a的地址) 指针变量存储的是别人的地址
printf("指针变量p的地址是:%p\n",p);//0019FF2C 指针变量存储别人的地址(a的地址)
printf("指针变量p的值是:%d\n",*p);//3 *取值也就是a的值
return 0;
}
八:指针变量需要开空间
1字节8位、32位操作系统
32位指针变量开空间是4字节(存储的内容是int数据类型,因此下面示例开空间4字节)
与基类型无关 与存储的内容有关
#include<stdio.h>
int main()
{
int a=3,b=4;
int *p=NULL;//定义1 定义并赋初值
char *pt=NULL;
p=&a;
//指针变量开空间的大小
printf("%d\n",sizeof(p)); // 4 int指针
printf("%d\n",sizeof(pt)); // 4 char指针
return 0;
}
九:void* 数据类型
void的使用:
1. 函数类型
2. void*类型指针代表该对象地址,但是没有该对象地址的信息
示例如 : void* k;// 0强制转换为void*和NULL类似
指针好处:不局部,不消亡,用于函数数据传递,传参
按地址传递,函数内部变化,外部也可以改变
&取地址 【%p】
*取值 【%d】
只有变量才可以取地址,值不可以取地址 【不可:&*p】
*&是可以的,先有地址,才可以取值
*&a==a先取a的地址再取a的值,本式正确
十:指针的偏移
指针是地址,因此是可以指针偏移的
指针的偏移 和 数据类型 有关,示例如下:
*p++:是先p++进行地址的偏移,再取值*,地址变化为28--》2c 偏移4位
(int类型指针偏移4位)
若是char类型指针则偏移1位,也就是说指针偏移量是根据基础数据类型来决定的
(*p)++是先取值再自增1