您的位置:首页 > 编程语言 > C语言/C++

C语言快速入门之指针

2018-02-27 16:53 375 查看

指针

大家都知道C语言的灵魂是指针,指针可以说是C语言中最难学的部分,只有掌握了指针,才能说C语言入门了。当然,我们之前已经掌握了数组的基本概念和使用,那么指针其实也就不那么神秘了。现在先来介绍一级指针。
char *p;    在这里,我们定义了一个指向char类型变量的指针p,但是没有让它指向任何地址,可以称之为野指针。指针,顾名思义,就是具有指向的作用。
 char *p=&a;   我们让p指向a的地址,&表示取地址的意思。当指针p指向变量a的地址,我们就可以通过对指针p的操作,来实现对a的操作。char a='c';    printf("a is =%c\n',*p);    会打印c,如果a的类型是int型,比如int a=100;    printf("a is =%c\n',*p); ,将不会打印100,而是打印100对应的ascii值d,因为%c输出的是字符型。如果将输出中的%c改成%d呢,能不能输出100?也是可以的,只不过会有警告,提示“不兼容指针类型的初始化”。所以,指针不可“随意指”需要指向对应的类型。
*p的*表示解引用,即取出变量p中的地址的值。注意:p只是一个变量,里面存放的是地址,*p才是指针,通过*把变量p中的地址取出来。char *p中的char是规定指针p指向的类型。如果是int *p,那么指向的是int类型的指针,才能打印我们希望的值。

指针数组与数组指针

相信初学C语言的时候,对指针数组是很陌生的,当时我学的时候就是数组勉强理解,到指针就已经晕了。经过不断的接触,慢慢的发现其实它们并不神秘,只要我们了解了它们的构造和概念,就可以在随后的编程中,逐步掌握了,现在,我们先来剖析一下二者。
char (*p)[2]和char *p[2]    这两个哪个是指针数组?    可以通过一个方法来区别,即表达式有没有括号()。
char *p[2]是没有括号的,所以我们就可以直接判断,它是一个指针数组。指针数组强调的是数组,所以不会对*p加上括号。
char (*p)[2] 是数组指针,*p是用括号括起来的,所以数组指针强调的是指针
好了,现在我们就可以很快的区别谁是数组指针,谁是指针数组了。
指针数组
类型 *变量名[数组长度];
顾名思义,指针数组,即存放指针的数组,数组的成员是指针 ,因为如果我们需要使用到多个指针,每次都定义一个新的指针,将会比较繁琐,所以指针数组,孕育而生。其实说白了,指针数组就是数组中存放了几个地址连续的指针。
比如,int *p[2];    我们定义了一个指向int类型的指针数组,int a=100;    int b=200;  然后将a和b的地址分别存放在变量p[0]和p[1]中,p[0]=&a;    p[1]=&b;    打印一下,printf("p[0]=%d,p[1]=%d\n",*p[0],*p[1]);    输出p[0]=100,p[1]=200;    这个简单的例子说明了指针数组的确是存放指针的数组。
char *pa;
int *pb;
printf("sizeof pa is =%d\n",sizeof(pa));    //打印4
printf("sizeof pb is =%d\n",sizeof(pb));    //打印4
printf("sizeof *pa is =%d\n",sizeof(*pa));    //打印1

printf("sizeof *pb is =%d\n",sizeof(*pb));    //打印4
记得我之前笔试的时候,经常会有上述 关于指针所占字节大小的填空题。
数组指针
类型(*变量名)[数组长度];
介绍了指针数组,现在我们来看看数组指针。数组指针,是指向数组的指针。比如char (*p)[5];    该指针p指向具有5个char类型成员的数组空间。一般使用的指针,如char a[10]="hello";    char *p=a;    表示该指针指向数组a,其实是指向了数组首元素a[0]的地址。这就是区别所在。来看下面一段代码。

char msg[2][3]={1,2,3,4,5,6};
char buf[2][3];
memset(buf,0,sizeof(buf));

char (*pc)[3]=buf; //数组指针
char (*pd)[3]=msg;
int i=0;
for(i;i<6;i++)
{
printf("msg is =%d,",*(*pd+i));
}
printf("\n");    //换行
scanf("%s",*(pc));    //输入
printf("buf is %s\n",*buf);

乍一看,是不是觉得有点凌乱,我们慢慢来剖析这段代码。首先我们定义了msg和buf两个二维数组,并且初始化msg。然后定义了两个数组指针,pc和pd。先来看pd,我们让pd指向数组msg,然后就可以通过操作pd来实现对数组msg的操作。我们用一个for循环来打印出msg中所有的元素。重点是*(*pd+i)    先来看看*p,*p的意思是取出变量p中地址里的值,我们可以把*(*pd+i)看成是*p,即*pd+i=p,这就很好理解了。*pd指向msg,所以*pd存放的是msg[0][0]的地址,*pd+1存放的是msg[0][1]的地址,依次类推,这就是为什么*pd要加i。所以*(*pd+i)   打印出了msg所有的元素。为了验证上述说法,我们来打印一下*pd的地址。
printf("p of *pd is=%p\n",*pd);
printf("p of msg[0][0] is=%p\n",msg[0]);

printf("p of *pd+1 is=%p\n",*pd+1);

printf("p of msg[0]+1 is=%p\n",msg[0]+1);
编译发现,*pd和msg[0]的地址一样,*pd+1和msg[0]+1的地址也一样。没错,*pd存放的是地址,它指向了msg的地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: