Joker

导航

指针2

指针

一级指针

int a,b;
int *p;

定义一个int型的指针p
指针是用来存放地址p = &a;
* 就是解地址的
使用指针的时候,没有它,你是不可能读写某块内存的。b = *p = a = 8;
指针的大小 sizeof(p) = 4; 在32位机,无论什么类型的指针大小都为4个byte。

int *p = NULL;

这句代码的意思是:定义一个指针
变量p,其指向的内存里面保存的是int类型的数据;在定义变量p的同时把p
的值设置为
0x00000000,而不是把*p的值设置为0x00000000。这个过程叫做初始化,是在编译的时候进行的。

int *p;
*p = NULL;//错误

第一行代码,定义了一个指针变量p,
其指向的内存里面保存的是int类型的数据;
但是这时候变量p本身的值是多少不得而知,
也就是说现在变量p保存的有可能是一个非法的地址。

第二行代码,给*p赋值为NULL,
即给p指向的内存赋值为NULL。
但是由于p指向的内存可能是非法的,
所以调试的时候编译器可能会报告一个内存访问错误。
这样的话,我们可以把上面的代码改写改写,使p指向一块合法的内存:

int i = 10;
int *p = &i;
*p = NULL;

p指向的内存由原来的10变为0了;
而p 本身的值,即内存地址并没有改变。

NULL 是空字符ASCII 码值为0 但与0 有本质的区别

 

多级指针

      所谓的多级指针,就是一个指向指针的指针,比如:

      char *p = "my name is chenyang.";

      char **pp = &p;//二级指针

      char ***ppp = &pp;//三级指针

      假设以上语句都位于函数体内,则可以使用下面的简化图来表达多级指针之间的指向关系。

      

//n级指针变量名Pn等于取n-1级指针变量名Pn-1,int ***Pn,**Pn-1;Pn=&(Pn-1);
#include <stdio.h>
int main (){
 int a = 2;
 int *p,**pp,***ppp;
 p=&a;
 pp=&p;
 ppp=&pp;
 printf("p = %d\npp = %d\nppp = %d\n",*p, **pp, ***ppp);
} 

指针的类型

从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型:

int*ptr;//指针的类型是int*
char*ptr;//指针的类型是char*
int**ptr;//指针的类型是int**
int(*ptr)[3];//指针的类型是int(*)[3]
int*(*ptr)[4];//指针的类型是int*(*)[4]

指针所指向的类型

当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。例如:

int*ptr; //指针所指向的类型是int
char*ptr; //指针所指向的的类型是char
int**ptr; //指针所指向的的类型是int*
int(*ptr)[3]; //指针所指向的的类型是int()[3]
int*(*ptr)[4]; //指针所指向的的类型是int*()[4]

 

指针数组 Type *p[n]

指针数组:是数组——装着指针的数组。

#include "stdio.h"
int main()
{
int a = 1;
int b = 2;
int *p[2];
p[0] = &a;
p[1] = &b;
printf("%p\n", p[0]); //a的地址
printf("%p\n", &a); //a的地址
printf("%p\n", p[1]); //b的地址
printf("%p\n", &b); //b的地址
printf("%d\n", *p[0]); //p[0]表示a的地址,则*p[0]表示a的值
printf("%d\n", *p[1]); //p[1]表示b的地址,则*p[1]表示b的值
//将二维数组赋给指针数组
int *pp[3]; //一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2],所以要分别赋值
int c[3][4];
for (int i = 0; i<3; i++)
pp[i] = c[i];//pp[0]=c[0]={c[0][0],c[0][1],c[0][2],c[0][3]};
return 0;
}

数组指针 Type (*p)[n]

数组指针:是指针——指向数组的指针。

#include "stdafx.h"
int main()
{
//一维数组
int a[5] = { 1, 2, 3, 4, 5 };
int(*p)[5];
p = &a;//把数组a的地址赋给p,则p为数组a的地址,则*p表示数组a本身
printf("%p\n", a); //输出数组a的地址,一般用数组的首元素地址来标识一个数组
printf("%p\n", p); //根据上面,p为数组a的地址,输出数组a的地址
printf("%p\n", *p); //*p表示数组a本身,一般用数组的首元素地址来标识一个数组
printf("%p\n", &a[0]); //a[0]的地址
printf("%p\n", &a[1]); //a[1]的地址
printf("%p\n", p[0]); //数组首元素的地址
printf("%d\n", **p); //*p表示地址,则*(*p)表示值,当*p表示数组首元素地址时,**p表示首元素本身,即首元素的值1
printf("%d\n", *p[0]); //根据优先级,p[0] 表示首元素地址,则*p[0]表示首元素本身,即首元素的值1
printf("%d\n", *p[1]); //错误,不表示a[1]...表示什么我还不知道
//将二维数组赋给指针
int b[3][4];
int(*pp)[4]; //定义一个数组指针,指向含4个元素的一维数组
pp = b; //将该二维数组的首地址赋给pp,也就是b[0]或&b[0],二维数组中pp=b和pp=&b[0]是等价的
pp++; //pp=pp+1,该语句执行过后pp的指向从行b[0][]变为了行b[1][],pp=&b[1]
return 0;
}
 把栈上的数据作为参数,若要修改其值,需将其作为指针传入函数(形如:栈上数据:int *p=a;  形参类型:int**   ;函数传参:func(&p);) 


指针函数
函数指针
结构体指针
函数作形参

posted on 2018-09-27 15:29  Joker·GS  阅读(170)  评论(0编辑  收藏  举报