1、什么是地址?
内存是由若干个1个字节的内存单元组成的存储器
计算机为了管理内存单元,给每个字节都进行编号
编号的就是地址
2、什么是指针?
地址就是指针
地址:
地址指向的内存单元值:编号对应的存储内容
变量访问的方法:直接访问
间接访问
1)直接访问:用变量名访问其代表的存储空间
2)间接访问:通过内存地址访问地址所对应的存储单元的内容
3、指针和变量之间的关系
指针可以间接的访问变量的值
1)指针变量:就是用来存放地址的变量
指针变量也遵守变量使用的规则
:先定义 --->初始化 -->使用
2)如何定义一个指针变量
数据类型*
指针变量名;
int *p;
//变量名 p
//int表示什么意思?
表示指针变量只能存放一个整型数据的地址
//* 什么意思? int p;//普通的整型变量,int *p;//指针变量
3)指针变量初始化
为什么要进行初始化?
首先,如果普通的一个变量没有初始化,会有什么后果? //垃圾值
对于指针变量,int *p; //p
随机的,p 0xff1111 10
*p = 10; //如果不初始化直接使用,可能会导致系统崩溃
野指针:定义之后,没有初始化
(1)定义的同时进行初始化
int *p=NULL; //赋值为NULL ,表示谁都不指
int *p1 = 0; //同上
int a=10;
int *p2=&a;
int *p3=&a;
int *p4 = p2;
p3 = p4; //指针的指向可以改变
(2)先定义,后出初始化
int *p;
p = NULL;
int *p1;
p1=&a;
注意:
1)多个指针可以指向同一个变量
2)指针的指向是可以改变的
3) int *p; p = 100;//错误的
存放的时地址,现在给的时整数值
4)*p = &a;错误 //*p是整型的变量,只能赋值数值
3)使用指针变量间接的访问变量值
int *p = &a;
*p 就是访问p中存放的地址代表的存储空间的值
p指向的存储空间的值
4、指针的应用场景
1)在被调函数中,修改主调函数的变量值
2)可以让函数有多个返回值
5、指针变量为什么要区分类型
前提:不同类型的指针变量在内存中占用8个字节
为什么都占用8个字节还要区分类型呢?
char *c; //c存放的时地址 *c
从c存放的地址开始
,连续取1个字节
int *p; *p 从p存放的地址开始
,连续取4个字节
int a=10;
char *c2 = &a; //从变量a的首地址开始,取了1个字节(实际4个,取少了)
double *d1 = &a; //从变量a的首地址开始,取了8个字节(实际4个,取多了)
6、多级指针介绍
二级及以上的指针
一级:指针指向的是一个基本数据类型变量的地址
二级:指向的又是一个地址
int a = 10;
int *p = &a; //p是一级
int **p1 = &p; //p1 ---> p p1是二级
7、指针和数组之间的关系
1)数组指针:
指向数组元素的指针变量
int a[5]; //a[0] a[1] 直接访问
目标:用地址也可以访问数组元素
(1)数组名访问
a存放的是数组的首地址(常量) == &a[0]
*a == a[0]元素的值
a+1 指向数组的下一个元素
a-1 指向数组的上一个元素
*a+1 == a[0]+1;
*(a+1) == a[1]元素的值
int *p; //指针变量
p = a; //p指向了数组a的第一个元素
p = &a[0];
p+1 指向数组的下一个元素
p-1 指向数组的上一个元素
*p == a[0]元素的值
*p+1 == a[0]+1;
*(p+1) == a[1]元素的值
p = p+1; //p移动到了下一个元素
p++;
*p++ == *(p++) == *(p = p+1)
2)指针数组:
指针数组:数组的每一个元素都是一个指针
int a[2][3]={1,2,3,4,5,6}; // a[0] 1,2,3 a[1] 4,5,6
int *pa[]={a[0],a[1]};
printf("%d\n",**(pa+1)); //4