您的位置:首页 > 其它

其实“指针”也没那么困难

2013-02-16 14:25 190 查看

指针确实是C/C++学习过程中的一大难点,但是它真正的难度就在于你很容易把它和普通变量搞混淆,更搞不清楚什么时候该用指针。本文针对初学者,将指针的概念逐步展示出来,希望能给初学者一点点帮助。

1、指针是什么东西?

指针其实是一个变量,它保存的值是其他变量在内存中的地址。

所以,在声明指针的时候,必须是要先有其他变量,才能有指针。而且,只能将既有变量用“&”取地址以后赋值给指针。下面的代码列举出了两种指针的声明方式,必须是先有变量num1,才能有指针p。

int num1=3;
int *p=NULL;        //如果声明的时候不立即给指针赋值,则指针必须为空值
p=&num1;

int num1=3;
int *p=&num1;   //声明的同时给指针赋值

2、为什么指针也要带数据类型名?

我们来看代码中的int *p,千万不要认为这个指针p是int类型的。指针自己就是一个独立的数据类型,在指针前面带上数据类型名,表示:这个指针保存的是某种数据类型的地址,即“指向某种类型”。如果是int *p,就表示:这个指针保存的是一个int变量的地址,即:指向一个int类型的变量。

什么叫“指向”?如果一个指针p保存了变量num1的地址,即将&num1赋值给p,就说指针p指向num1.

指针前面带的数据类型,一定要和它指向的变量数据类型吻合

int num1=3;
int *p=&num1;    正确
char *p=&num1;   错误,指针指向的类型和num1的类型不匹配

3、不同地方的“*”有着不同的含义

在声明指针的时候,必须有“*”号,表示:我声明的变量是一个指针。声明指针的时候,“*”号表示的是指针变量的特殊标记。

int *p;   声明一个指向int类型变量的指针p
int p;    (没有“*”)声明的是一个普通int型变量p

float *pt;   声明的是一个指向float类型变量的指针pt
float pt;    声明的是一个普通的float型变量pt

在使用指针的时候,“*”号的含义就表示:从指针标记的地址中取出里面的值。只有在对指针做取值操作的时候,才允许给指针带上“*”,如果是给指针赋值为其他变量的地址,则指针不能带“*”号了。

int *a=9;
int *p=NULL;

p=&a;     //给指针赋值地址时不能带“*”号
*p=8;     //给指针赋值其他整数值时,必须带“*”号

*p=2.5    错误操作,因为p是一个指向int类型的指针,*p只能赋值整数
p=6;      错误操作,指针本身不能赋值为任何整数

p++       可以操作,但一般不这么使用,让指针指向下一个int类型的变量(这个变量必须存在)
(*p)++    正确操作,让指针指向的变量值进行自加

有人会问了:既然内存地址是表示成一个16进制的整数,那也可以用一个long long int来表示地址,干嘛要用指针呢? 原因很简单:用一个long long int的变量确实可以标记其他变量的地址,但是非指针类型的变量只能标记地址,不支持取值操作

int num1=9;
int *p1=&num1;              //用指针标记num1的地址
long long int p2=&num1;    //用超长整形变量p2标记num1的地址

printf("变量num1的地址是:%p\n",p1);
printf("变量num1的地址是:%p\n",p2);
//这里,他们输出的结果都是一样的

区别在这里:

*p1;   正确,可以用“*”从指针p中取出它指向的变量(num1)的值
*p2;  错误,(会提示“没有左值”)

4、指针和变量的地址到底有什么关系?

假设有一个指针:int *p=&a,此时用*p、a、*(&a)都可以取出a的值。那么问:p和&a有什么联系和区别?

p是一个指针,而指针是一个变量,它的值可以任意改变,只有当p=&a操作时,p的值才和&a的值相同,如果p被赋值了其他的值,它就不和&a相等了。

而a的地址——&a是一个常量,只要程序开始运行,&a的值就不会改变。

可以给p赋值,但是不能给&a赋值

int a=3;
int b=5;

int *p1=&a;    让p1指向变量a
int *p2=&b;    让p2指向变量b

p1=p2;       指针p2的值赋值给p1,允许的操作 ,操作后,p1也指向变量b了
&a=&b;       错误的操作,变量的地址之间不能互相赋值

5、指针可以进行加减运算吗?

只有指向相同数据类型的指针,才能进行算术运算。

但是,两个指针不能做加法运算。因为两个地址相加,无任何意义

这好比是:张三住在201寝室,李四住在202寝室,则张三的指针值就是201,李四的指针值是202,两个指针相加得到403,这没有任何意义。
但是指针可以相减,而且只有指向相同数据类型的指针才能相减。相减的结果是这两个变量在内存中,相差几个sizeof(数据类型)的地址。(只有在数组中,指针相减才能发挥作用。数组存储结构参见博文http://wzjxzht.blog.51cto.com/4866070/1134011)

#include <stdio.h>

int main(void)
{
int arr[3]={1,2,3};
int *p1=&arr[1];
int *p2=&arr[2];

printf("%d\n",p2-p1);
return 0;
}
程序运行结果:1,表示p1和p2之间的差值是一个int类型的字节长度

指针可以和整数进行加减,指针加1,表示:指针原来的值,加上它指向的变量的数据类型的字节长度,即sizeof(数据类型)

[code]#include <stdio.h> int main(void) { int a=0; int *p=&a; printf("sizeof(int)=%d\n",sizeof(int)); printf("p=%p\n",p); printf("p+1=%p\n",p+1); return 0; } 程序运行结果: sizeof(int)=4 p=0012FF60 p+1=0012FF64

这表示,p+1等于0012FF60+sizeof(int)==0012FF60+4==0012FF64

指针减一就和指针加1的含义相反了。

指针加n:指针原来的值+n×sizeof(指针指向的变量数据类型)

指针减n;指针原来的值-n×sizeof(指针指向的变量数据类型)

对于指针和整数加减,只适用于数组中,当指针p指向数组中某一个元素时,指针p+1,就等于让指针p指向数组下一个元素,指针p-1,就等于让指针p指向数组上一个元素。

6、总结:指针的用法流程

(1)先声明其他变量

(2)再声明相应类型的指针,让指针赋值让&变量的值

(3)如果操作的时候,给指针带*号,表示从指针取值,如果不带“*”号,表示指针与指针之间进行地址操作。

本文就针对指针的概念进行的部分阐述,相信大家只要仔细理解,一定能够攻克指针这一难关的。

[/code]

本文出自 “捷哥的IT小屋” 博客,请务必保留此出处http://wzjxzht.blog.51cto.com/4866070/1134105
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: