指针基础(一)
指针其实就是内存地址。
普通变量定义形式:
int a=10,b=20,c=30;
printf("a=%d,b=%d,c=%d\r\n",a,b,c);
变量存储在内存里面 ,&取地址符找到存放在内存中的哪个位置
printf("a地址=%d,b地址=%d,c地址=%d\r\n",&a,&b,&c);
#p打印就是16进制打印 #可以打印出来0x
printf("a地址=%#p,b地址=%#p,c地址=%#p\r\n",&a,&b,&c);
指针常量:&a,&b,&c ;
指针变量: 存储的是地址
p类型就是char*, 指向char型的指针
char* p;
靠近char和靠近变量名字没有区别。
char *p1;
char *p2;
指针一定要进行初始化,没有初始化的指针无法使用
int *pa = &a;
printf("pa=%d",pa);
空指针(NULL)
int *pd = NULL;
#define和typedef的区别
N的类型是 int 类型,预处理全部替换
M的类型是 int 起别名 预处理不会全部替换 这种类型就代表int
#define MYINT int
typedef int MYPLUSINT;
MYINT N;
MYPLUSINT M;
无法和定义一串整型一样定义一串指针变量。
只有p1是指针变量。
#define PMYINT *int
PMYINT p1,p2,p3,p4;
//正确用法
int* p1,*p2,*p3,*p4;
这里定义了4个指针变量。
typedef int* PMYPLUSINT;
PMYPLUSINT p1,p2,p3,p4;
指针和地址的关系如下图所示:
指针基础(二)
指针的间接访问运算符:* :间接访问运算符(解引用运算符)。
打印出a的地址:
printf("&*a=%d\n",&*pa);
打印出a的值:
printf("*a=%d\n",*&a);
空指针打印出空指针的地址:
int *pd = NULL;
printf("*pa=%d\r\n",pd);
指针也可以改变指向。
int *pa = &a;
printf("pa=%d\n",*pa);
pa = &c;
printf("pa=%d\n",*pa);
二级指针
二级指针指向一级指针的指针
指针有地址
int* pa,*pb,*pc;
pa = &a;
pb = &b;
pc = &c;
printf("pa的地址%d,pb的地址%d,pc的地址%d",&pa,&pb,&pc);
int** ppa = &pa,** ppb = &pb,** pc = &pc;
二级指针示意图:
二级指针存储的是一级指针的地址。
二级指针也可以改变指向。两个指针指向同一个值。
ppb = &pc;
进行间接访问
*ppa = &a;
使用二级指针修改数值。
** ppc = 600;
//关系: **ppc = *(*ppc) = *pc = c;
三级指针
三级指针
int ***pppa = &ppa;
非法指针
无法间接访问。
int *px;
printf("*pa=%d\r\n",*px);
因此使用指针不安全,要判断是不是为NULL,不是NULL的时候才可以访问。
正确使用方法。
if(pe!=NULL)
printf("pe = %d\n",*pe);
指针和int型变量有什么关系?
int *pf = (int*)123456;
printf("pf = %d",pf);
指针所占内存的大小
不管什么类型的指针都占用4个字节。
int *pf;
char *pch;
double *pdouble;
printf("pf的大小:%d\n",sizeof(pf));
printf("pf的大小:%d\n",sizeof(pch));
printf("pf的大小:%d\n",sizeof(pdouble));